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

发布于 2024-07-24 09:05:11 字数 557 浏览 6 评论 0原文

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

例如,

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 的限制?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

后来的我们 2024-07-31 09:05:11

如果您从 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()};

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()};
心碎的声音 2024-07-31 09:05:11

我遇到了同样的问题,并且希望保留在查询语法中使用扩展方法的能力(与普通支持的函数一样......)。 解决方案可能是这个库(剧透:我是作者)。

您只需实现该方法即可重用两次,一次用于一般用途,一次用于查询。

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 方法调用(如果进行了相应标记)。 因此,您可以在查询中的任何位置使用扩展方法——参数化方法也可以工作。

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.

醉生梦死 2024-07-31 09:05:11

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

此处查找文章。

您可以将用于投影重用的程序集作为 nuget 包 获取,源位于 CodePlex

自从你发帖以来已经过去了一段时间了。 我希望它仍然对你有帮助。 如果没有,也许对于其他阅读此帖子的人来说。

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.

心不设防 2024-07-31 09:05:11

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文