2010-10-06 10 views
25

Ich habe eine Erweiterungsmethode, um Linq dynamisch nach Entities-Ergebnissen mit String-Werten zu filtern. Es funktioniert gut, bis ich es nutze, um Nullable-Spalten zu filtern. Hier ist mein Code:Arbeiten mit Nullable-Typen in Ausdrucksbaumstrukturen

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

Hier ist, wie ich es verwenden:

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

Hier ist die Ausnahme, die ich immer bin, wenn ich das für Nullable-Tabellenspalten:

Der binäre Operator GreaterThanOrEqual ist nicht definiert für die Typen 'System.Nullable`1 [System.Int32]' und 'System.Int32'

Ich konnte das nicht herausfinden. Was soll ich machen?

+0

mögliches Duplikat von [Expression.GreaterThan schlägt fehl, wenn eins o Perand ist Nullable-Typ, andere ist nicht nullbar] (http://stackoverflow.com/questions/2088231/expression-greaterthan-fails-if-one-operand-isnullable-type-other-is-non-nulla) – nawfal

Antwort

31

ich den Wert Typ auf den Spaltentyp mit Expression.Convert zu konvertieren hatte:..

Expression where = Expression.GreaterThanOrEqual(column, Expression.Convert(Expression.Constant(value), column.Type)); 
+0

Ich mache genau das gerade jetzt. Ich benutzte 'Expression.Constant (value, column.Type)' Das heißt, mein Fall ist ein bisschen komplizierter, weil alle meine Filterwerte Strings sind (keine Objekte, die ein konvertierbarer Typ sein sollten: int -> int ?, bool -> Bool ?, usw.). Ich muss also nicht nur die Ausdrücke dynamisch erstellen, sondern auch die Filterwerte in den Typen, die den Spalten entsprechen. – JoeBrockhaus

+1

Ich habe gerade meinen Code geändert, der diesen Fehler zuvor ausgelöst hat. Die Verwendung von 'Expression.Convert' war viel einfacher als die Überprüfung, ob der Typ Nullable war (durch Reflektion), und wenn dies der Fall war, wurde der Ausdruck (als eine Rückkehr von meiner Hilfsmethode) mit einem explizit erzeugten' Nullable <> 'erstellt. Ich werfe die Zeichenfolge einfach auf den gewünschten Werttyp (int, bool usw.) und dann auf "Expression.Convert (Expression.Constant (castValue), columnType)". Boom. Danke für diesen Fund! – JoeBrockhaus

+0

@JoeBrockhaus warum nicht einfach den Typ mit der 'Expresson.Constant' verwenden, ob es NULL erlaubt ist oder nicht? Genau das würde ich auch hier als Antwort empfehlen. –

-1

Sie können prüfen, ob ein Typ NULL-Werte zulässt, indem Sie:. If (typeof (T) .Equals (typeof (Nullable <>)) Ich glaube, und dann, dass speziell behandeln vorgehen Wenn Sie die GetValueOrDefault aufrufen können() -Methode das würde irgendwie, arbeiten oder programmbly den Vergleichswert schaffen vielleicht vom gleichen Typ sein

HTH