IQueryable.Where() 适合在哪里表达?

发布于 2024-10-07 20:14:28 字数 537 浏览 1 评论 0原文

我对 .NET 中的表达式 的经验非常少,这就是为什么我宁愿问你们。 我该怎么办 - 请参阅下面的评论:

using P = Myclass;
..
System.Linq.Expressions.Expression<Func<P, bool>> myExpression = null;
..
myExpression1 = x => foo1 == true && foo2 == false;
myExpression2 = x => ... ;
..
BinaryExpression resultExpression = System.Linq.Expressions.Expression.OrElse(myExpression1, myExpression2);
..
IQueryable<P> l = l.Where(?resultExpression?); // how to transform BinaryExpression to the suitable type?

谢谢

I'm very low experienced with Expressions in .NET, that's why I rather ask you guys.
How should I - see comment below:

using P = Myclass;
..
System.Linq.Expressions.Expression<Func<P, bool>> myExpression = null;
..
myExpression1 = x => foo1 == true && foo2 == false;
myExpression2 = x => ... ;
..
BinaryExpression resultExpression = System.Linq.Expressions.Expression.OrElse(myExpression1, myExpression2);
..
IQueryable<P> l = l.Where(?resultExpression?); // how to transform BinaryExpression to the suitable type?

Thank you

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

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

发布评论

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

评论(4

隔岸观火 2024-10-14 20:14:28

您不能以这种方式将 lambda 一起“或”在一起。你确实想将 lambda 体“或”在一起。这是一种方法:

public static Expression<Func<T, bool>> OrTheseFiltersTogether<T>( 
  this IEnumerable<Expression<Func<T, bool>>> filters) 
{ 
    Expression<Func<T, bool>> firstFilter = filters.FirstOrDefault(); 
    if (firstFilter == null) 
    { 
        Expression<Func<T, bool>> alwaysTrue = x => true; 
        return alwaysTrue; 
    } 

    var body = firstFilter.Body; 
    var param = firstFilter.Parameters.ToArray(); 
    foreach (var nextFilter in filters.Skip(1)) 
    { 
        var nextBody = Expression.Invoke(nextFilter, param); 
        body = Expression.OrElse(body, nextBody); 
    } 
    Expression<Func<T, bool>> result = Expression.Lambda<Func<T, bool>>(body, param); 
    return result; 
} 

然后:

Expression<Func<P, bool>> myFilter1 = x => foo1 == true && foo2 == false;  
Expression<Func<P, bool>> myFilter2 = x => ... ;  
..  
List<Expression<Func<P, bool>>> filters = new List<Expression<Func<P, bool>>>();
filters.Add(myfilter1);
filters.Add(myfilter2);
..  
Expression<Func<P, bool>> resultFilter = filters.OrTheseFiltersTogether();
IQueryable<P> query = query.Where(resultFilter);

You can't "OR" lambdas together that way. You really want to "OR" the lambda bodies together. Here's a method to do that:

public static Expression<Func<T, bool>> OrTheseFiltersTogether<T>( 
  this IEnumerable<Expression<Func<T, bool>>> filters) 
{ 
    Expression<Func<T, bool>> firstFilter = filters.FirstOrDefault(); 
    if (firstFilter == null) 
    { 
        Expression<Func<T, bool>> alwaysTrue = x => true; 
        return alwaysTrue; 
    } 

    var body = firstFilter.Body; 
    var param = firstFilter.Parameters.ToArray(); 
    foreach (var nextFilter in filters.Skip(1)) 
    { 
        var nextBody = Expression.Invoke(nextFilter, param); 
        body = Expression.OrElse(body, nextBody); 
    } 
    Expression<Func<T, bool>> result = Expression.Lambda<Func<T, bool>>(body, param); 
    return result; 
} 

Then later:

Expression<Func<P, bool>> myFilter1 = x => foo1 == true && foo2 == false;  
Expression<Func<P, bool>> myFilter2 = x => ... ;  
..  
List<Expression<Func<P, bool>>> filters = new List<Expression<Func<P, bool>>>();
filters.Add(myfilter1);
filters.Add(myfilter2);
..  
Expression<Func<P, bool>> resultFilter = filters.OrTheseFiltersTogether();
IQueryable<P> query = query.Where(resultFilter);
箜明 2024-10-14 20:14:28

您可能想看一下 Predicatebuilder:

http://www.albahari.com/ nutshell/predicatebuilder.aspx

Predicatebuilder 允许您以非常干净且易于理解的方式运行一些非常强大的表达式(AND/OR/NOT 等)。对于简单的表达式,我当然只是从头开始滚动它们并应用,但对于复杂的东西......

我非常喜欢它:)

SO 本身的一些链接可能会有所帮助:

LINQ to SQL PredicateBuilder

使用 PredicateBuilder、LINQPad 和运算符 ANY 生成 SQL

you might want to take a wee look at the Predicatebuilder:

http://www.albahari.com/nutshell/predicatebuilder.aspx

the Predicatebuilder allows you to run up some very powerful expressions (AND/OR/NOT etc, etc) in a very clean and easy to understand way. For simple expressions, I do of course just roll them from scratch and apply but for the complex stuff...

I'm quite a fan of it :)

a few links on SO itself that may be helpful:

LINQ to SQL PredicateBuilder

Generated SQL with PredicateBuilder, LINQPad and operator ANY

凑诗 2024-10-14 20:14:28

.Where 方法采用 lambda 表达式作为参数,因此您需要将 BinaryExpression 构建为完整的 LambdaExpression

var resultExpression = Expression.OrElse(myExp1, myExp2);   
   // now the exp is like: p > 100 || p < 10
ParameterExpression parameterExp = Expression.Parameter(typeof(P),"p");
   // construct a parameter with its type P, looks like: p =>
LambdaExpression lambdaExp = Expression.Lambda(resultExpression, parameterExp);
   // merge the two expressions:  p => p > 100 || p < 10
myList.Where(lambdaExp.Compile());

.Where method takes a lambda expression as a parameter, so you need to build your BinaryExpression to a complete LambdaExpression.

var resultExpression = Expression.OrElse(myExp1, myExp2);   
   // now the exp is like: p > 100 || p < 10
ParameterExpression parameterExp = Expression.Parameter(typeof(P),"p");
   // construct a parameter with its type P, looks like: p =>
LambdaExpression lambdaExp = Expression.Lambda(resultExpression, parameterExp);
   // merge the two expressions:  p => p > 100 || p < 10
myList.Where(lambdaExp.Compile());
﹏半生如梦愿梦如真 2024-10-14 20:14:28

它是表达式级别上两个 Func

的组合。

一种不太花哨的方法应该是:

Func<P, bool> myExpression1 = x => foo1 == true && foo2 == false;
Func<P, bool> myExpression2 = x => ... ;

IQueryable<P> l = l.Where((p) => myExpression1(p) || myExpression2(p));

Its a combination of two Func<P, bool> on expression level.

A less fancy way to do the same should be:

Func<P, bool> myExpression1 = x => foo1 == true && foo2 == false;
Func<P, bool> myExpression2 = x => ... ;

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