Working with nullable types in Expression Trees
19,839
Solution 1
I had to convert the value type to the column type using Expression.Convert:
Expression where = Expression.GreaterThanOrEqual(column, Expression.Convert(Expression.Constant(value), column.Type));
Solution 2
A type can be passed to the Expression.Constant function as a second argument. Something like typeof(int?) or, in the case of this question, column.Type.
e.g.
Expression.Constant(value, column.Type)
Author by
themiurge
Updated on June 03, 2022Comments
-
themiurge almost 2 years
I have an extension method to dynamically filter Linq to Entities results using string values. It works fine until I use it to filter nullable columns. Here's my code:
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); }
Here's how I use it:
var results = (from row in ctx.MyTable select row) .OrderingHelperWhere("userId", 5);//userId is nullable column
Here's the exception I'm getting when I use this for nullable table columns:
The binary operator GreaterThanOrEqual is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'
I couldn't figured this out. What should I do?
-
JoeBrockhaus almost 10 yearsI'm doing this very thing right now. I used
Expression.Constant(value, column.Type)
That said, my case is a bit more complicated because all my filter values are strings (not objects that should be a convertible type: int -> int?, bool -> bool?, etc). So not only do I need to create the expressions dynamically, but also the filter values in the types that match the columns. -
JoeBrockhaus almost 10 yearsJust changed back my code that was throwing this error before. Using
Expression.Convert
was FAR easier than dealing with checking if the type was Nullable (using reflection), and if so creating the Expression (as a return from my helper method) with an explicitly createdNullable<>
). I simply cast the string to the desired value type (int, bool, etc), thenExpression.Convert(Expression.Constant(castValue), columnType)
. boom. thanks for this find! -
Jon Hanna about 7 years@JoeBrockhaus why not just use the type with the
Expresson.Constant
whether it's nullable or not? Indeed, that's what I'd recommend as the answer here too. -
Seabizkit about 5 yearsLove you, this helped alot
-
GilShalit over 2 yearsThis is a brilliant solution