I like to reuse expressions for DRY reasons, but how do I reuse the expressions within a LINQ statement?
e.g.
I have
public static class MyE
By the way, I've come across this useful article which explains how you can create dynamic LINQ Queries that reference functions wrapped as Expressions using a custom ToExpandable() extension method. The solution provided can be used within the various parts of a LINQ Query all while preserving the use of comprehension syntax instead of resorting to lambda syntax.
We had the same problem. It is not supported out of the box and it is a major problem for LOB applications. I ended up writing a code-project article about LINQ expressions reuse, including a very small utility called LinqExpressionPrjection that enables the reuse in projections (including into anonymous types).
Find the article here.
You can get the assembly for the projection reuse as a nuget package and the source is on CodePlex.
Some time has passed since your post. I hope it is still helpful for you. If not, maybe for others reading this thread.
If you move from the LINQ syntactic sugar it is possible:
var goodProds = dataContext.Products.Where(MyExpressions.IsAGoodProduct());
Without it, it isn't possible.
There's nothing to stop you mixing the two styles to build a single query though.
Example:
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()};
I had the same problem and wanted to preserve the ability to use extension methods within the query syntax (as with ordinary supported functions...). A solution might be this library (spoiler: I‘m the author).
You just implement the method to reuse twice, once for general use and once for queries.
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;
}
}
The actual query can then look like expected.
var goodProds = from p in dataContext.Products.ToInjectable()
where p.IsAGoodProduct()
select p;
The ToInjectable
call creates a lightweight proxy, which replaces the IsAGoodProduct
method call (if marked accordingly) with the desired lambda expression. Thus, you can use extension methods wherever within the query -- parameterized methods work as well.