简体   繁体   中英

How to filter IQueryable containing nullable types using expression trees?

I have model class MyModel with a Nullable property: Field1 . I'm trying to filter the queryable of MyModel based on Field1 using an expression tree. The part I handle nullable is as below:

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

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

Here, ConvertExpressionType() converts the type of the expression so that it can be used with Condition expression.

In debug, the full queryable looks like below:

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

Here, Field2 is a second field of type long . I'm trying to make sure the timespan sum of Field1 and Field2 are less than a given value.

However, when I try to enumerate the queryable, after about 2 elements, I get the NullReferenceException . If I just try a dummy value in expression tree instead of null , I can avoid it like:

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

So, I guess, I'm doing something wrong in the conditional expression. How can I fix this (or figure out exactly what is causing the exception?

Without even checking, I would say that the problem is

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

because first null constant has no type ( Expression.Constant(null).Type is typeof(object) though) and second and more importantly, for sure cannot be converted to TimeSpan (or any non nullable value type ).

It's not quite clear what does Field1 null value mean. In case you want to treat it as zero, then replace the above with

Expression.Constant(TimeSpan.Zero)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM