2017-09-25 81 views
2

此刻我有一个linq查询,其中存在一个方法。我收到错误LINQ to Entities does not recognize the method。所以我发现我可以将该方法转换为表达式LINQ to Entities does not recognize the method,但我想知道是否有一种干净而简单的方式将表达式添加到我的linq查询中。在linq查询中使用表达式

原始方法

public bool IsAvailable() 
{ 
    return Eligibility.ProgramType == InteractionProgramTypes.Available; 
} 

改为

public System.Linq.Expressions.Expression<Func<InteractionProgram, bool>> IsAvailable() 
{ 
    return i => i.Eligibility.ProgramType == InteractionProgramTypes.Available; 
} 

的LINQ查询而不表达

x => x.ActivityDate <= endDate && x.IsAvailable() 

Linq查询与表达

x => x.ActivityDate <= endDate && x.IsAvailable().Compile() 

当我这样做时,我得到编译器错误,& &运算符不能应用于操作数。

请问我该如何将表达式追加到我当前的linq查询中。

+0

你是什么意思'.Compile()',这是什么结果? –

+0

@JericCruz https://msdn.microsoft.com/en-us/library/bb345362(v=vs.110).aspx – Master

+0

错误是由SQL提供的吗?或编译/解释? – GGO

回答

0

既然你已经转换IsAvailable返回Expression<Func<InteractionProgram,bool>>,所有你需要做的是通过调用此方法的Where方法IQueryable<T>的结果:

var res = ctx.InteractionPrograms.Where(InteractionProgram.IsAvailable()); 

注意,为了让这个来编译方法需要是静态的。此外,你可以把一个属性的甚至更好的可读性:

class InteractionProgram { 
    public static Expression<Func<InteractionProgram,bool>> IsAvailable {get;} = 
     i => i.Eligibility.ProgramType == InteractionProgramTypes.Available; 
    ... // other members of the class 
} 

... 
var res = ctx.InteractionPrograms.Where(InteractionProgram.IsAvailable); 

那其他条件x.ActivityDate < =结束日期。那去哪里?

其他条件在IsAvailable条件之前或之后立即分开Where条款。 EF驱动程序将为您组合这两个表达式,从而在RDBMS端产生一个查询。

另一种替代方法,以共享该表达式将被创建基于返回IQueryable<InteractionProgram>预滤波关于可用性EF上下文扩展方法:

public static IQueryable<InteractionProgram> AvailableInteractionPrograms(this MyDbContext dbCtx) => 
    dbXtx.InteractionPrograms.Where(i => 
     i.Eligibility.ProgramType == InteractionProgramTypes.Available 
    ); 

这隐藏的共享方法背后的功能。

+1

我很好奇 - 为什么它必须是静态的? – Chris

+2

@Chris因为它不使用实例中的任何内容。基本上,表达式有一个额外的“元间接”级别 - 而不是直接在“this”实例上运行,它会产生一个操作(一个函数),它可以在您选择传递给它的任何实例上进行操作。但是,在这种情况下,根本不会传递实例。相反,EF驱动程序会将功能分开,并使用其内容来构建SQL条件。 – dasblinkenlight

+0

你说什么对我来说是有道理的,为什么它可以是静态的,我仍然不确定我明白它为什么必须是静态的。编译器实际给出了什么错误我没有测试环境来测试我自己... – Chris