AndAlso之间的几个防爆pression< Func键< T,布尔>> :从适用范围引用 [英] AndAlso between several Expression<Func<T, bool>> : referenced from scope

查看:124
本文介绍了AndAlso之间的几个防爆pression< Func键< T,布尔>> :从适用范围引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个predicates,我想作一个 AndAlso 之间。我发现主板上的几个样本,但是解决不了我的问题。

I have 3 predicates, I'd like make an AndAlso between. I found several sample on the board, but can't solve my problem.

这些predicates是:防爆pression< Func键< T,布尔>>

These predicates are : Expression<Func<T, bool>>

我有这个code:

Expression<Func<T, bool>> predicate1 = ......;
Expression<Func<T, bool>> predicate2 = ......;
Expression<Func<T, bool>> predicate3 = ......;

我创建一个扩展方法,使一个AndAlso:

I create an extension method to make an "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]);
}

我用的是这样的:

I use like this :

var finalPredicate = predicate1
    .AndAlso<MyClass>(predicate2)
    .AndAlso<MyClass>(predicate3);

在predicate看看这个:

The predicate look this :

当我在查询中使用:

var res =  myListAsQueryable().Where(finalPredicate).ToList<MyClass>();

我得到这个错误: 的可变型的'生成器predicate.MyClass'的'p'从范围''引用,但它没有定义

I get this error : variable 'p' of type 'BuilderPredicate.MyClass' referenced from scope '', but it is not defined

你能告诉我什么是错的?

Could you tell me what's wrong ?

感谢了很多,

推荐答案

问题创造了一种新的参数 - 你可以这样做,但如果你只是把它分配给最终的拉姆达,还有你的参数和原始之间没有连接在所提供的前pressions参数。尝试前pressions不断变化的参数名称,然后检查最后predicate 。你会看到类似这样的:

The problem is creating a new parameter - you can do that, but if you simply assign it to the final lambda, there's no connection between your parameter and the original parameters in the provided expressions. Try changing param names of the expressions and then check the finalPredicate. You will see something like:

{p => (((x.Age == 42) AndAlso (y.Salary == 50)) AndAlso z.FirstName.StartsWith("foo"))}

这个问题现在应该是显而易见的。

The problem should be obvious now.

马克Gravell建议在 这个答案 一般防爆pression.AndAlso ,这正是你所需要的:

Marc Gravell suggest in this answer a general Expression.AndAlso, which is exactly what you need:

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);
}

(code马克,不是我)

(code by Marc, not me)

这篇关于AndAlso之间的几个防爆pression&LT; Func键&LT; T,布尔&GT;&GT; :从适用范围引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆