Как отфильтровать IQueryable, содержащий обнуляемые типы, используя деревья выражений? - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть класс модели MyModel со свойством Nullable: Field1. Я пытаюсь отфильтровать запрос 100 * на основе 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. Я пытаюсь убедиться, что сумма временного интервала Field1 и Field2 меньше заданного значения.

Однако, когда я пытаюсь перечислить запрашиваемую информацию, примерно через 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 голосов
/ 16 ноября 2018

Даже не проверяя, я бы сказал, что проблема в

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

, потому что первая null константа не имеет типа (хотя Expression.Constant(null).Type равно typeof(object)), а вторая и, что более важно, навернякане может быть преобразовано в TimeSpan (или любой тип значения, не обнуляемый ).

Не совсем ясно, что означает Field1 нулевое значение.Если вы хотите обработать его как ноль, то замените вышеуказанное на

Expression.Constant(TimeSpan.Zero)
...