我想通过使用表达式树使LINQ查询的某些部分可重用(我认为这就是调用方式)。
这是我的查询的简化版本:
var lQuery =
from m in ...
join a in ... into ta
from ra in ta.DefaultIfEmpty()
select
new {
...
Status = ra != null ? ... : ..., /* <- i want this to be reusable */
...
};
如您所见,Status的值是通过
? :
语法确定的,该语法由LINQ自动翻译(我想是一个表达式树,SQL日志最后显示一个CASE WHEN
查询)。如何将代码移至单独的函数,以使我的应用程序在运行时不会引发
not supported
异常?我尝试添加一个功能
public static System.Linq.Expressions.Expression<System.Func<%type of ra%, %status type%>>
QueryStatusExpression()
{
return ra => ra != null ? ... : ...;
}
然后像
Status = QueryStatusExpression().Invoke(ra)
但是会抛出
not supported
异常。我现在没主意了。任何帮助表示赞赏。
最佳答案
可以通过LINQKit项目的combined expressions
解决此问题。
方法如下:
将LinqKit
引用添加到您的项目中(例如,通过NuGet程序包管理器)。
在.cs文件顶部添加以下行,以使LINQKit的扩展方法可用
using LinqKit; // for System.Linq.Expressions.Expression<>.Invoke()
将表达式定义为静态字段
public static System.Linq.Expressions.Expression<
System.Func<%type of ra% ra, %status type%>>
GetStatusExpression = ra != null ? ... : ...;
调用查询中的表达式(请确保如LINQKit文档中所述将.AsExpandable()添加到第一个表中)
var lQuery =
from m in %first table%.AsExpandable() ...
join a in ... into ta
from ra in ta.DefaultIfEmpty()
select
new {
...
Status = GetStatusExpression.Invoke(ra),
...
};
如果要在“普通”代码中使用表达式,则需要先进行编译,例如
public static System.Func<%type of ra% ra, %status type%>
GetStatusExpressionCompiled = GetStatusExpression.Compile();
...
if (GetStatusExpressionCompiled(ra) == ...)
{
...
非常感谢svick的评论为我指明了正确的方向。
关于c# - 如何将LINQ查询的一部分移至可重用的LINQ表达式树,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29348825/