Kri*_*s-I 6 .net c# lambda expression
我有3个谓词,我想要AndAlso介于两者之间.我在板上发现了几个样本,但无法解决我的问题.
这些谓词是: Expression<Func<T, bool>>
我有这个代码:
Expression<Func<T, bool>> predicate1 = ......;
Expression<Func<T, bool>> predicate2 = ......;
Expression<Func<T, bool>> predicate3 = ......;
Run Code Online (Sandbox Code Playgroud)
我创建了一个扩展方法来创建一个"AndAlso":
public static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr,
Expression<Func<T, bool>> exprAdd)
{
var param = Expression.Parameter(typeof(T), "p");
var predicateBody = Expression.AndAlso(expr.Body, exprAdd.Body);
return Expression.Lambda<Func<T, bool>>(predicateBody, param);
//Tried this too
//var body = Expression.AndAlso(expr.Body, exprAdd.Body);
//return Expression.Lambda<Func<T, bool>>(body, expr.Parameters[0]);
}
Run Code Online (Sandbox Code Playgroud)
我用这样的:
var finalPredicate = predicate1
.AndAlso<MyClass>(predicate2)
.AndAlso<MyClass>(predicate3);
Run Code Online (Sandbox Code Playgroud)
谓词看起来像这样:

当我在查询中使用时:
var res = myListAsQueryable().Where(finalPredicate).ToList<MyClass>();
Run Code Online (Sandbox Code Playgroud)
我得到这个错误: 从范围''引用的'BuilderPredicate.MyClass'类型的变量'p',但它没有定义
你能告诉我什么是错的吗?
非常感谢,
Hon*_*tan 11
问题是创建一个新参数 - 您可以这样做,但如果您只是将其分配给最终的lambda,则您的参数与提供的表达式中的原始参数之间没有任何关联.尝试更改表达式的param名称,然后检查finalPredicate.你会看到类似的东西:
{p => (((x.Age == 42) AndAlso (y.Salary == 50)) AndAlso z.FirstName.StartsWith("foo"))}
Run Code Online (Sandbox Code Playgroud)
问题现在应该是显而易见的.
Marc Gravell在这个答案中建议一般Expression.AndAlso,这正是你需要的:
public static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
// need to detect whether they use the same
// parameter instance; if not, they need fixing
ParameterExpression param = expr1.Parameters[0];
if (ReferenceEquals(param, expr2.Parameters[0]))
{
// simple version
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(expr1.Body, expr2.Body), param);
}
// otherwise, keep expr1 "as is" and invoke expr2
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
expr1.Body,
Expression.Invoke(expr2, param)), param);
}
Run Code Online (Sandbox Code Playgroud)
(Marc代码,不是我)
| 归档时间: |
|
| 查看次数: |
7110 次 |
| 最近记录: |