Работа с обнуляемыми типами в деревьях выражений - PullRequest
29 голосов
/ 06 октября 2010

У меня есть метод расширения для динамической фильтрации результатов Linq to Entities с использованием строковых значений. Он работает нормально, пока я не использую его для фильтрации пустых столбцов Вот мой код:

public static IOrderedQueryable<T> OrderingHelperWhere<T>(this IQueryable<T> source, string columnName, object value)
{
    ParameterExpression table = Expression.Parameter(typeof(T), "");
    Expression column = Expression.PropertyOrField(table, columnName);
    Expression where = Expression.GreaterThanOrEqual(column, Expression.Constant(value));
    Expression lambda = Expression.Lambda(where, new ParameterExpression[] { table });

    Type[] exprArgTypes = { source.ElementType };

    MethodCallExpression methodCall = Expression.Call(typeof(Queryable), 
                                                      "Where", 
                                                      exprArgTypes, 
                                                      source.Expression, 
                                                      lambda);

    return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(methodCall);
}

Вот как я это использую:

var results = (from row in ctx.MyTable select row)
              .OrderingHelperWhere("userId", 5);//userId is nullable column

Вот исключение, которое я получаю, когда использую это для столбцов таблицы, допускающих обнуляемость:

Бинарный оператор GreaterThanOrEqual не определен для типов 'System.Nullable`1 [System.Int32]' и 'System.Int32'

Я не мог понять это. Что мне делать?

Ответы [ 2 ]

50 голосов
/ 07 октября 2010

Мне пришлось преобразовать тип значения в тип столбца, используя Expression.Convert:

Expression where = Expression.GreaterThanOrEqual(column, Expression.Convert(Expression.Constant(value), column.Type));
0 голосов
/ 06 октября 2010

Вы можете проверить, является ли тип обнуляемым, выполнив: if (typeof (T) .Equals (typeof (Nullable <>)), я верю, а затем продолжу обрабатывать это специально. Если вы можете каким-либо образом вызвать метод GetValueOrDefault (), это сработает, или программная сборка создаст значение сравнения того же типа, может быть.

HTH.

...