【问题标题】:How to filter IQueryable containing nullable types using expression trees?如何使用表达式树过滤包含可为空类型的 IQueryable?
【发布时间】:2019-04-19 07:29:40
【问题描述】:

我的模型类 MyModel 具有 Nullable 属性:Field1。我正在尝试使用表达式树根据Field1 过滤MyModel 的可查询项。我处理可为空的部分如下:

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

这里,Field2long 类型的第二个字段。我试图确保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))
)

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

【问题讨论】:

    标签: c# expression-trees iqueryable


    【解决方案1】:

    甚至不检查,我会说问题是

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

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

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

    Expression.Constant(TimeSpan.Zero)
    

    【讨论】:

      猜你喜欢
      • 2011-04-21
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 2020-11-12
      相关资源
      最近更新 更多