表达式树生成UnWanted Invoke

时间:2017-08-24 13:45:36

标签: c# expression-trees

(这是最初的标题,表达式树比较DateTime与Nullable DateTime,但正如接受的答案所示,这根本不是问题。)

我正在尝试构建表达式树来比较实体框架查询中的日期。在下面的示例中,'结果'是已传递给方法的IQueryable,而DateFilter是来自UI的对象,该UI具有可为空的DateTime字段,FirstDate,SecondDate和枚举,DateType和DateMode。

我见过很多类似的问题,常见的线程似乎是使用Expression.Convert来确保日期的类型正确。但是,我仍然做错了,因为当我走到尽头,而不是(System.Nullable'1[System.DateTime]$x.EffectiveDate >= ...我的表达有.Invoke(.Constant<TheClassIAmIn i.e., 'this'+<>c__DisplayClass47_0>('this'+<>c__DisplayClass47_0).resultFunc)( $x, ......

以下是完整代码段:

        var changeInfo = Expression.Parameter(typeof(MyEntity), "x");
        var targetDate = Expression.Property(changeInfo, DateFilter.DateType.ToString());

        var dateFilter = Expression.Parameter(typeof(MyDateFilter), "DateFilter");
        var firstDate = Expression.Property(dateFilter, "FirstDate");
        var secondDate = Expression.Property(dateFilter, "SecondDate");

        //  Note that FirstDate, SecondDate, and ActionDate are nullable,
        //  SubmittedDate and EffectiveDate are not.
        var ge = Expression.GreaterThanOrEqual(Expression.Convert(targetDate, firstDate.Type), firstDate);

        var tree =
            Expression.Lambda<Func<MyEntity, MyDateFilter, bool>>
            (ge, changeInfo, dateFilter);

    var resultFunc = tree.Compile();
            result = result.Where(x => resultFunc(x, MyDateFilter));

1 个答案:

答案 0 :(得分:4)

此问题与DateTimeNullable<DateTime>比较没有任何共同之处。

你看到的表达方式是:

Expression<Func<MyEntity, bool>> expr = x => resultFunc(x, MyDateFilter);

是lambda表达式,参数x 调用 resultFunc变量,其中包含Func<MyEntity, MyDateFilter, bool>类型的委托

你不应该引入MyDateFilter 参数,这会产生不兼容的lambda表达式,不应该编译委托并发出调用表达式。相反,您应该直接构建类型为Expression<Func<MyEntity, bool>>的lambda表达式。 MyDateFilter值将作为Expression.Constant传递:

var changeInfo = Expression.Parameter(typeof(MyEntity), "x");
var targetDate = Expression.Property(changeInfo, DateFilter.DateType.ToString());

// Assuming DateFilter is a field/property/variable of type MyDateFilter    
var dateFilter = Expression.Constant(DateFilter);
var firstDate = Expression.Property(dateFilter, "FirstDate");
var secondDate = Expression.Property(dateFilter, "SecondDate");

var ge = Expression.GreaterThanOrEqual(
    Expression.Convert(targetDate, firstDate.Type),
    firstDate);

var predicate = Expression.Lambda<Func<MyEntity, bool>>(
    ge, changeInfo);

result = result.Where(predicate);