How can I reuse expressions within LINQ statements?

后端 未结 4 1584
南笙
南笙 2020-12-14 17:03

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         


        
相关标签:
4条回答
  • 2020-12-14 17:22

    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.

    0 讨论(0)
  • 2020-12-14 17:23

    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.

    0 讨论(0)
  • 2020-12-14 17:26

    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()};
    
    0 讨论(0)
  • 2020-12-14 17:40

    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.

    0 讨论(0)
提交回复
热议问题