如何在LINQ语句中重用表达式?

CVe*_*tex 20 c# linq lambda

我喜欢为DRY原因重用表达式,但是如何在LINQ语句中重用表达式?

例如

我有

public static class MyExpressions {
    public static Expression<Func<Product,bool>> IsAGoodProduct() {
        return (p) => p.Quality>3;
    }
}
Run Code Online (Sandbox Code Playgroud)

并且想在LINQ语句中使用它,所以

  var goodProds = from p in dataContext.Products
                  where ????? // how do I use IsAGoodProduct here?
                  select p;
Run Code Online (Sandbox Code Playgroud)

当然,我可以使用IQueryableExtension.Where函数,但这会使连接和其他函数对于更复杂的查询更加困难.

这是可能的还是LINQ的限制?

Gar*_*ler 23

如果你从LINQ语法糖转移,它是可能的:

var goodProds = dataContext.Products.Where(MyExpressions.IsAGoodProduct());
Run Code Online (Sandbox Code Playgroud)

没有它,就不可能.

没有什么可以阻止你混合两种样式来构建单个查询.

例:

  var goodProds = from p in dataContext.Products
                                       .Where(MyExpressions.IsAGoodProduct())
                  group p by p.Category into g 
                  select new {Category = g.Key, ProductCount = g.Group.Count()};
Run Code Online (Sandbox Code Playgroud)


Axe*_*eer 5

我遇到了同样的问题,并希望保留在查询语法中使用扩展方法的能力(与普通支持的函数一样......)。一个解决方案可能是这个库(剧透:我是作者)。

您只需实现重复使用两次的方法,一次用于一般用途,一次用于查询。

public static class MyFunctions {
    [InjectLambda]
    public static bool IsAGoodProduct(Product product) {
        return product.Quality>3;
    }
    public static Expression<Func<Product,bool>> IsAGoodProduct() {
        return (p) => p.Quality>3;
    }
}
Run Code Online (Sandbox Code Playgroud)

实际的查询可能看起来像预期的那样。

var goodProds = from p in dataContext.Products.ToInjectable()
                where p.IsAGoodProduct()
                select p;
Run Code Online (Sandbox Code Playgroud)

ToInjectable调用创建了一个轻量级代理,它用IsAGoodProduct所需的 lambda 表达式替换方法调用(如果相应标记)。因此,您可以在查询中的任何地方使用扩展方法——参数化方法也能工作。