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

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

例如

我有

public static class MyExpressions { public static Expression<Func> IsAGoodProduct() { return (p) => p.Quality>3; } } 

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

  var goodProds = from p in dataContext.Products where ????? // how do I use IsAGoodProduct here? select p; 

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

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

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

 var goodProds = dataContext.Products.Where(MyExpressions.IsAGoodProduct()); 

没有它,就不可能。

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

例:

  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()}; 

我们遇到了同样的问题。 它不支持开箱即用,它是LOB应用程序的主要问题。 我最后编写了一篇关于LINQ表达式重用的代码项目文章,包括一个名为LinqExpressionPrjection的非常小的实用程序,它可以在投影中重用(包括匿名类型)。

在这里找到文章。

您可以将投影重用的程序集作为nuget包获取 ,源代码可以在CodePlex上 。

你的post已经过了一段时间了。 我希望它对你有用。 如果没有,可能是其他人阅读这个post。

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

您只需将方法实现两次,一次用于一般用途,一次用于查询。

 public static class MyFunctions { [InjectLambda] public static bool IsAGoodProduct(Product product) { return product.Quality>3; } public static Expression> IsAGoodProduct() { return (p) => p.Quality>3; } } 

然后,实际查询看起来像预期的那样。

 var goodProds = from p in dataContext.Products.ToInjectable() where p.IsAGoodProduct() select p; 

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

顺便说一句,我遇到过这篇有用的文章 ,它解释了如何创建动态LINQ查询,使用自定义ToExpandable()扩展方法引用包装为表达式的函数。 提供的解决方案可以在LINQ查询的各个部分中使用,同时保留使用理解语法而不是求助于lambda语法。