将 Linq MemberExpression lambda 转换为在类上使用引用

发布于 2024-08-13 06:30:49 字数 1702 浏览 3 评论 0 原文

对于这个问题,我将使用 Products(带有 IsActive 标志)和 OrderItems(每个都引用一个 Product)的标准结构。我还有一个查询生成器,可以生成用于查询产品的 Linq 表达式。示例过滤器可以让用户查找活动/非活动产品,生成一个 Linq 表达式,例如:

Expression<Func<Product, bool>> testProductActive = product => !product.IsActive;

我想采用该表达式并使用它来测试 IQueryable。我可以使用Expression.Invoke来处理内存中的集合:

public static Expression<Func<TDestination, TResult>> Translate<TSource, TDestination, TResult>(this Expression<Func<TSource, TResult>> @this, Expression<Func<TDestination, TSource>> getSourceFromDestination)
{
    ParameterExpression param = Expression.Parameter(typeof(TDestination), "arg");

    Expression invokedGetSource = Expression.Invoke(getSourceFromDestination, param);
    Expression invokedOriginalBody = Expression.Invoke(@this, invokedGetSource);

    Expression<Func<TDestination, TResult>> result = Expression.Lambda<Func<TDestination, TResult>>(invokedOriginalBody, param);
    return result;
}

我会这样称呼它:

Expression<Func<OrderItem, bool>> testOrderItemProductActive = testProductActive.Translate<Product, OrderItem, bool>(orderItem => orderItem.Product);

但是NHibernate.Linq(从我在问题中看到的,Linq to Entities)不支持<代码>表达式.调用

有没有办法从 testProductActive 获取 MemberExpression 并将其转换为 !orderItem.Product.IsActive


注意:在现实生活中的示例中,我将拥有由可见过滤器生成的 Expression> 表达式的集合,这些表达式都需要转换。现在,我已经让过滤器为两种类型的记录生成表达式,但我希望删除重复项并使其能够将现有过滤器用于不同类型的记录,而无需更改过滤器自己的代码。

For this question, I'll use the standard structure of Products (with an IsActive flag) and OrderItems (that each reference a Product). I also have a query builder that generates Linq expressions used to query products. A sample filter would let the user find active/inactive products, generating a Linq expression like:

Expression<Func<Product, bool>> testProductActive = product => !product.IsActive;

I want to take that expression and use it to test an IQueryable<OrderItem>. I can do it with in-memory collections using Expression.Invoke:

public static Expression<Func<TDestination, TResult>> Translate<TSource, TDestination, TResult>(this Expression<Func<TSource, TResult>> @this, Expression<Func<TDestination, TSource>> getSourceFromDestination)
{
    ParameterExpression param = Expression.Parameter(typeof(TDestination), "arg");

    Expression invokedGetSource = Expression.Invoke(getSourceFromDestination, param);
    Expression invokedOriginalBody = Expression.Invoke(@this, invokedGetSource);

    Expression<Func<TDestination, TResult>> result = Expression.Lambda<Func<TDestination, TResult>>(invokedOriginalBody, param);
    return result;
}

Which I would call like:

Expression<Func<OrderItem, bool>> testOrderItemProductActive = testProductActive.Translate<Product, OrderItem, bool>(orderItem => orderItem.Product);

But NHibernate.Linq (and from what I've seen in questions, Linq to Entities) does not support Expression.Invoke.

Is there a way to take the MemberExpression from testProductActive and turn it into !orderItem.Product.IsActive?


Note: In a real-life example, I would have a collection of Expression<Func<Product, bool>> expressions generated by visible filters that would all need converted. Right now I've got my filters generating expressions for both types of records, but I'd love to drop the duplication and make it so an existing filter could be used for a different type of record without changing the filter's own code.

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

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

发布评论

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

评论(1

摇划花蜜的午后 2024-08-20 06:30:49

它与您的提议不太一样,但请查看 动态 Linq。

It's not in quite the same vein as what you're proposing, but check out Dynamic Linq.

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