我喜欢为DRY原因重用表达式,但是如何在LINQ语句中重用表达式呢?
e.g。
我有
public static class MyExpressions {
public static Expression<Func<Product,bool>> 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的限制?
答案 0 :(得分:22)
如果您从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()};
答案 1 :(得分:3)
我们遇到了同样的问题。它不是开箱即用的支持,它是LOB应用程序的主要问题。我最后编写了一篇关于LINQ表达式重用的代码项目文章,包括一个名为LinqExpressionPrjection的非常小的实用程序,它可以在投影中重用(包括匿名类型)。
找到文章here。
您可以将投影重新使用的汇编作为nuget package,并且源位于CodePlex。
自您发布以来已经过了一段时间。我希望它对你有用。如果没有,也许是其他人阅读这个帖子。
答案 2 :(得分:3)
我遇到了同样的问题,并希望保留在查询语法中使用扩展方法的能力(与普通支持的函数一样......)。解决方案可能是this library。
您只需将该方法重复使用两次,一次用于一般用途,一次用于查询。
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;
}
}
然后,实际查询可能看起来像预期的那样。
var goodProds = from p in dataContext.Products.ToInjectable()
where p.IsAGoodProduct()
select p;
ToInjectable
调用创建一个轻量级代理,它用所需的lambda表达式替换IsAGoodProduct
方法调用(如果相应地标记)。因此,您可以在查询中的任何位置使用扩展方法 - 参数化方法也可以。
答案 3 :(得分:1)
顺便说一下,我遇到了这个useful article,它解释了如何创建动态LINQ查询,使用自定义ToExpandable()扩展方法引用包装为表达式的函数。提供的解决方案可以在LINQ查询的各个部分中使用,同时保留comprehension syntax的使用,而不是使用lambda语法。