如何使用表达式树过滤包含可空类型的IQueryable?

时间:2018-11-16 06:01:36

标签: c# expression-trees iqueryable

我有一个模型类MyModel,其属性为NullableField1。我正在尝试使用表达式树基于MyModel过滤Field1的可查询项。我处理可为空的部分如下:

var memEx = Expression.Property(parameterEx, "Field1");

var memberEx = Expression.Condition(
    Expression.Property(memEx , "HasValue"),
    Expression.Property(memEx, "Value),
    ConvertExpressionType(Expression.Constant(null), typeof(TimeSpan))
)

在这里,ConvertExpressionType()转换表达式的类型,以便可以与Condition表达式一起使用。

在调试中,完整的可查询内容如下所示:

{System.Collections.Generic.List`1[MyModel].Where(x => ((IIF(x.Field1.HasValue, x.Field1.Value, Convert(null, TimeSpan)) + x.Field2.ToTimeSpan()) < 06:49:08.3313919))}

在这里,Field2是类型long的第二个字段。我正在尝试确保Field1Field2的时间总和小于给定值。

但是,当我尝试枚举可查询对象时,经过大约2个元素,我得到了NullReferenceException。如果我只是在表达式树中尝试使用虚拟值而不是null,则可以避免出现这种情况:

var memEx = Expression.Property(parameterEx, "Field1");

var memberEx = Expression.Condition(
    Expression.Property(memEx , "HasValue"),
    Expression.Property(memEx, "Value),
    ConvertExpressionType(Expression.Constant(TimeSpan.FromHours(1)), typeof(TimeSpan))
)

所以,我想我在条件表达式中做错了什么。我该如何解决(或找出导致异常的确切原因?

1 个答案:

答案 0 :(得分:3)

我什至没有检查,就是问题所在

ConvertExpressionType(Expression.Constant(null), typeof(TimeSpan))

因为第一个null常量没有类型(Expression.Constant(null).Typetypeof(object)),第二个(更重要的是)一定不能转换为TimeSpan(或任何非空值类型)。

目前还不清楚Field1空值是什么意思。如果您想将其视为零,则将上面的内容替换为

Expression.Constant(TimeSpan.Zero)