【问题标题】:Composing LINQ Expressions编写 LINQ 表达式
【发布时间】:2012-05-03 21:13:03
【问题描述】:

我已经阅读了很多关于将 LINQ 表达式放在一起的文章,但它们似乎只涵盖了 and's 和 or's。我已经实施了这个解决方案:

http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx

如何编写此代码以使其正常工作?

Expression<Func<Crop, bool>> chooseOranges = crop => crop.IsOrange;
Expression<Func<Farm, bool>> selectFarm = farm => farm.HasCows;

selectFarm = selectFarm.And(farm => farm.Crops.Any(chooseOranges);

它可以编译,但在运行时会引发 .NET 1025 错误。如果我将 chooseOranges 替换为文字文本,它会起作用,但 chooseOranges 是使用业务逻辑逐段构建的。我上面链接的代码似乎依赖于各种 Expression.Foo() 函数,但我找不到一个有用的函数。

【问题讨论】:

    标签: c# linq lambda


    【解决方案1】:

    使用LinqKit 的能力来评估嵌套表达式并返回一个可由任何支持写出相同表达式的提供者使用的单个表达式:

    Expression<Func<Crop, bool>> chooseOranges = crop => crop.IsOrange;
    Expression<Func<Farm, bool>> selectFarm = farm => farm.HasCows;    
    Expression<Func<Farm, bool>> combined = (farm) => selectFarm.Invoke(farm) && farm.Crops.Any(inner => chooseOranges.Invoke(inner));
    combined = combined.Expand();
    

    【讨论】:

    • 可供任何提供者使用,他们也支持相同的表达方式。
    • 当我尝试运行最后一行时会引发 StackOverflowException。这是我的问题吗?
    • @MrEff 试试这个编辑,selectFarm 本地可能已被捕获
    • 看来定义一个新变量就足以让它工作了。谢谢。
    【解决方案2】:

    我会这样写:

    Expression<Func<Crop, bool>> chooseOranges = crop => crop.IsOrange;  
    Expression<Func<Farm, bool>> selectFarm = farm => farm.HasCows;  
    
    IQueryable farmQuery = GetQuery();
    farmQuery = farmQuery.Where(selectFarm);
    farmQuery = farmQuery.Where(farm => farm.Crops.Any(chooseOranges); 
    

    每一行必须同时满足两个条件才能出现在结果中,所以这就是 And。

    对于 Or,我是通过 there 完成的。

    【讨论】:

      猜你喜欢
      • 2010-09-08
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多