如何正确合并具有不同参数的lambda表达式

时间:2015-06-03 01:46:08

标签: c# lambda expression

我有两个表达方式:

SELECT a.ct veh_count, b.ct user_count, c.ct event_count, d.ct alert_count
FROM
( SELECT COUNT(*) ct FROM vehicles WHERE cus=1 ) a,
( SELECT COUNT(*) ct FROM user WHERE cus=1 ) b,
( SELECT COUNT(*) ct FROM vehicle_events WHERE cus=1 ) c,
( SELECT COUNT(*) ct FROM vehicle_alerts WHERE cus=1 ) d;

以下代码编译但只需要一个类型" long"的参数。组合lambda,如何将两个不同的参数传递给组合lambda?

3 个答案:

答案 0 :(得分:4)

Expression<Func<long, bool>> condition = x => x < max; // Exp # 1
Expression<Func<long, int, bool>> combined = null;

if (count > 0)
{
    Expression<Func<int, bool>> limit = x => x > -1; // Exp # 2
    combined = Expression.Lambda<Func<long, int, bool>>(
        Expression.And(condition.Body, limit.Body), 
        new ParameterExpression[] 
        {
            condition.Parameters[0], 
            limit.Parameters[0] 
        }
    );
} else {
    // Count <= 0, `int` parameter will be provided, but `body` ignores it
    combined = Expression.Lambda<Func<long, int, bool>>(
        condition.Body, 
        new ParameterExpression[] 
        {
            condition.Parameters[0], 
            limit.Parameters[0] 
        }
    );
}

// compile `combined` expression
var comparator = combined.Compile();

while (comparator(k++, n--))
{
    // Something
}

答案 1 :(得分:2)

首先,您需要将condition表达为两个输入。如果不与第二个表达式组合,请将第二个(未使用的)参数添加到lambda定义中。组合两个表达式时,在要组合的表达式周围添加Invoke。否则,您将收到运行时错误,告知您Func<int,bool>Func<long,bool>无法与&&运算符合并。

以下是如何实施它:

Expression<Func<long,int,bool>> condition;

Expression<Func<long,bool>> exp1 = x => x < max;

if (count > 0)
{
    Expression<Func<int,bool>> exp2 = x => x > -1;
    condition = Expression.Lambda<Func<long,int,bool>>(
            Expression.AndAlso(
                Expression.Invoke(exp1, exp1.Parameters)
            ,   Expression.Invoke(exp2, exp2.Parameters)
            )
        ,   exp1.Parameters.Concat(exp2.Parameters)
        );
} else {
    condition = Expression.Lambda<Func<long,int,bool>>(
        Expression.Invoke(exp1, exp1.Parameters)
        ,   exp1.Parameters.Concat(new[]{Expression.Parameter(typeof(int))})
        );
}
var comparator = condition.Compile();

Demo.

答案 2 :(得分:0)

我现在没有方便的Visual Studio,但是在预感中你是否试着看看它是否有效:

if (count > 0)
{
    Expression<Func<int, bool>> limit = x => x > -1; // Exp # 2
    condition = Expression.Lambda<Func<long, int, bool>>(
                Expression.AndAlso(condition, limit), condition.Parameters);
}

这将为新的组合Lambda提供一个签名,该签名接受两个参数并返回一个bool。您可能还需要在condition.Parameters之后执行一些操作,以包含l imit.parameters