我在.NET中使用Expressions
的经验很少,这就是为什么我宁愿问你们。
我该怎么做 - 看下面的评论:
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?
谢谢
答案 0 :(得分:5)
你不能用这种方式“或”羔羊。你真的想把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);
答案 1 :(得分:1)
你可能想看看Predicatebuilder:
http://www.albahari.com/nutshell/predicatebuilder.aspx
Predicatebuilder允许您以非常简洁易懂的方式运行一些非常强大的表达式(AND / OR / NOT等)。对于简单的表达式,我当然只是从头开始滚动它们但适用于复杂的东西......
我非常喜欢它:)
关于SO本身的一些链接可能会有所帮助:
Generated SQL with PredicateBuilder, LINQPad and operator ANY
答案 2 :(得分:0)
.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());
答案 3 :(得分:-2)
它是表达级别上两个Func<P, bool>
的组合。
这种不那么花哨的方式应该是:
Func<P, bool> myExpression1 = x => foo1 == true && foo2 == false;
Func<P, bool> myExpression2 = x => ... ;
IQueryable<P> l = l.Where((p) => myExpression1(p) || myExpression2(p));