Tutorial :How can I reuse expressions within LINQ statements?



Question:

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 MyExpressions {      public static Expression<Func<Product,bool>> IsAGoodProduct() {          return (p) => p.Quality>3;      }  }  

And would like to use that in LINQ statements, so

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

Sure, I could use the IQueryableExtension.Where function, but that would make joins and other functions alot uglier for more complex queries.

Is this possible or is it a limitation of LINQ?


Solution:1

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


Solution:2

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.


Solution:3

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.

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.


Solution:4

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.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »