我想通过使用表达式树使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/

10-17 00:15