Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带有多个输入选择器的表达式.Lambda_C#_Linq_Lambda - Fatal编程技术网

C# 带有多个输入选择器的表达式.Lambda

C# 带有多个输入选择器的表达式.Lambda,c#,linq,lambda,C#,Linq,Lambda,我正在尝试创建自己的自定义操作,可以在数据库中使用该操作查找受值更改影响的行 我正在看Jon Skeets之间的运算符示例:但我遇到了问题,因为我的操作包含多个参数输入 public static IQueryable<TSource> LeavingRange<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>&

我正在尝试创建自己的自定义操作,可以在数据库中使用该操作查找受值更改影响的行

我正在看Jon Skeets之间的运算符示例:但我遇到了问题,因为我的操作包含多个参数输入

    public static IQueryable<TSource> LeavingRange<TSource, TKey>(this IQueryable<TSource> source,
        Expression<Func<TSource, TKey>> lowKeySelector,
        Expression<Func<TSource, TKey>> highKeySelector,
        Nullable<TKey> oldValue,
        Nullable<TKey> newValue)
            where TKey : struct, IComparable<TKey>
    
这样做会产生以下错误:

为lambda声明提供的参数数量不正确

构造Lambda时,组合输入参数的正确方法是什么?


支持信息 下面是我的完整代码,但我认为相关的位是两个选择器和
表达式.Lambda
调用

    public static IQueryable<TSource> LeavingRange<TSource, TKey>(this IQueryable<TSource> source,
        Expression<Func<TSource, TKey>> lowKeySelector,
        Expression<Func<TSource, TKey>> highKeySelector,
        Nullable<TKey> oldValue,
        Nullable<TKey> newValue)
            where TKey : struct, IComparable<TKey>
    {
        Expression lowKey = Expression.Invoke(lowKeySelector, lowKeySelector.Parameters.ToArray());
        Expression highKey = Expression.Invoke(highKeySelector, highKeySelector.Parameters.ToArray());

        //is oldValue null which means it cant possibly be leaving
        var oldValueIsNotNull = Expression.NotEqual(Expression.Constant(oldValue, typeof(Nullable<TKey>)), Expression.Constant(null, typeof(Nullable<TKey>)));
        var newValueIsNull = Expression.Equal(Expression.Constant(newValue, typeof(Nullable<TKey>)), Expression.Constant(null, typeof(Nullable<TKey>)));
        var newValueIsNotNull = Expression.Not(newValueIsNull);

        var oldValueIsBetweenRange = Between(Expression.Convert(Expression.Constant(oldValue), typeof(TKey)), lowKey, highKey);
        var newValueIsNotBetweenRange = Expression.Not(Between(Expression.Convert(Expression.Constant(newValue), typeof(TKey)), lowKey, highKey));

        //IE leaving because its going from in the range to null
        var newValueIsNullAndOldValueIsBetweenRange = Expression.AndAlso(newValueIsNull, oldValueIsBetweenRange);

        var oldValueIsInRangeAndNewValueIsNot = Expression.AndAlso(newValueIsNotNull, Expression.AndAlso(oldValueIsBetweenRange, newValueIsNotBetweenRange));
        var isLeavingRange = Expression.AndAlso(oldValueIsNotNull, Expression.Or(newValueIsNullAndOldValueIsBetweenRange, oldValueIsInRangeAndNewValueIsNot));

        var leavingRange = Expression.Lambda<Func<TSource, bool>>(isLeavingRange, lowKeySelector.Parameters[0], highKeySelector.Parameters[0]);
        
        return source.Where(leavingRange);
    }
公共静态IQueryable LeavingRange(此IQueryable源,
表达式lowKeySelector,
表达式highKeySelector,
可为空的值,
可为空(新值)
其中TKey:struct,IComparable
{
表达式lowKey=Expression.Invoke(lowKeySelector,lowKeySelector.Parameters.ToArray());
表达式highKey=Expression.Invoke(highKeySelector,highKeySelector.Parameters.ToArray());
//oldValue为null,这意味着它不可能离开
var oldValueIsNotNull=Expression.NotEqual(Expression.Constant(oldValue,typeof(Nullable)),Expression.Constant(null,typeof(Nullable));
var newValueIsNull=Expression.Equal(Expression.Constant(newValue,typeof(Nullable)),Expression.Constant(null,typeof(Nullable));
var newValueIsNotNull=表达式.Not(newValueIsNull);
var oldValueIsBetweenRange=Between(Expression.Convert(Expression.Constant(oldValue)),typeof(TKey)),lowKey,highKey);
var newValueIsNotBetweenRange=Expression.Not(介于(Expression.Convert(Expression.Constant(newValue))、typeof(TKey))、lowKey和highKey之间);
//IE离开,因为它从范围内变为空
var newValueIsNullAndOldValueIsBetweenRange=表达式.AndAlso(newValueIsNull,oldValueIsBetweenRange);
var oldValueIsInRange和newValueIsNot=Expression.AndAlso(newValueIsNotNull,Expression.AndAlso(oldValueIsBetweenRange,newValueIsNotBetweenRange));
var isLeavingRange=Expression.AndAlso(oldValueIsNotNull,Expression.Or(newValueIsNullAndOldValueIsBetweenRange,oldValueisInRange and newValueisNot));
var leavingRange=Expression.Lambda(isLeavingRange,lowKeySelector.Parameters[0],highKeySelector.Parameters[0]);
返回源。其中(剩余范围);
}

传递给
Where()
的委托只将集合中的每个元素作为参数, 因此,您需要使调用
lowKeySelector
highKeySelector
的两个表达式将相同的元素(相同的
参数表达式实例
)作为参数 还需要构建lambda表达式以将其用作参数

public static IQueryable<TSource> LeavingRange<TSource, TKey>(this IQueryable<TSource> source,
     Expression<Func<TSource, TKey>> lowKeySelector,
     Expression<Func<TSource, TKey>> highKeySelector,
     Nullable<TKey> oldValue,
     Nullable<TKey> newValue)
         where TKey : struct, IComparable<TKey>
{
    ParameterExpression paramOfWhereDelg = Expression.Parameter(typeof(TSource), "p");

    Expression lowKey = Expression.Invoke(lowKeySelector, paramOfWhereDelg);
    Expression highKey = Expression.Invoke(highKeySelector, paramOfWhereDelg);

    // Build your expression tree
    //  ...

    var leavingRange = Expression.Lambda<Func<TSource, bool>>(isLeavingRange, paramOfWhereDelg);

    return source.Where(leavingRange);
}
公共静态IQueryable LeavingRange(此IQueryable源,
表达式lowKeySelector,
表达式highKeySelector,
可为空的值,
可为空(新值)
其中TKey:struct,IComparable
{
ParameterExpression paramofWeedelg=表达式参数(typeof(TSource),“p”);
表达式lowKey=Expression.Invoke(lowKeySelector,paramofWeedelg);
表达式highKey=Expression.Invoke(highKeySelector,paramofWeedelg);
//构建表达式树
//  ...
var leavingRange=表达式.Lambda(isLeavingRange,paramofWeedelg);
返回源。其中(剩余范围);
}
(或者您可以使用
lowKeySelector.Parameters
而不是
paramofweedelg

但是我相信创建另一个
参数表达式将更容易理解。)

我相信回答者Ripple已经解决了您的问题。对我来说,这似乎是一个合适的答案。但如果没有,我会注意到你没有发布一个,没有它很容易误解上下文或问题,或者至少很难提供一个足够清晰和具体的答案来满足你的需要。这非常有效,我不理解这个参数在做什么,看起来它只是lambda的输入。谢谢
public static IQueryable<TSource> LeavingRange<TSource, TKey>(this IQueryable<TSource> source,
     Expression<Func<TSource, TKey>> lowKeySelector,
     Expression<Func<TSource, TKey>> highKeySelector,
     Nullable<TKey> oldValue,
     Nullable<TKey> newValue)
         where TKey : struct, IComparable<TKey>
{
    ParameterExpression paramOfWhereDelg = Expression.Parameter(typeof(TSource), "p");

    Expression lowKey = Expression.Invoke(lowKeySelector, paramOfWhereDelg);
    Expression highKey = Expression.Invoke(highKeySelector, paramOfWhereDelg);

    // Build your expression tree
    //  ...

    var leavingRange = Expression.Lambda<Func<TSource, bool>>(isLeavingRange, paramOfWhereDelg);

    return source.Where(leavingRange);
}