2017-05-08 1 views
0

Ich versuche, eine Where-Klausel zu erstellen, die ich in einer Funktion und einer Eigenschaft übergeben kann, dann vergleichen Sie sie. Ich habe eine lange Liste von verschiedenen Eigenschaften, die ich vergleichen muss, also möchte ich eine Erweiterungsmethode, um es zu wickeln.Bedingte generische Where-Klausel in Entity Framework

Hier ist, wie ich will, es zu benutzen:

string transactionNumber = "12345"; 
Queryable<TranCard> transactions = _context.TranCard 
    .WhereEquals(t => t.TransactionNumber, transactionNumber) 
    .ToList(); 

Hier ist die Extension-Methode Ich habe zur Zeit das ist, was mir Probleme:

public static IQueryable<T> WhereEquals<T>(this IQueryable<T> source, Func<T, string> expression, string queryParam) 
    { 
     return source.Where(t => string.IsNullOrWhiteSpace(queryParam) 
           || expression != null 
           && string.Equals(queryParam.Trim(), expression.Invoke(t).Trim(), StringComparison.OrdinalIgnoreCase)); 
    } 

Wenn ich versuche, dies zu laufen es die folgenden Laufzeitfehler werfen message: "Falsche Anzahl der für den Aufruf der Methode angegebenen Argumente 'Boolean Equals (System.String, System.String, System.StringComparison)'"

+0

Gibt es einen Stack-Trace? Die Methode funktioniert gut für mich auf einer Liste von Objekten, so dass meine nächste Vermutung wäre, dass EF Schwierigkeiten hat, es zu vereinheitlichen. –

+2

So funktioniert Ausdruck nicht mit IQueryable. Sie müssen den Ausdrucksbaum für IQueryable generieren, anstatt ihn aufzurufen. Die Ausdrücke werden vom zugrunde liegenden Provider ausgewertet. @EdPlunkett Sie haben es funktioniert, weil das im Speicherobjekt und nicht Objekt für sql ist (der zugrunde liegende Anbieter benötigt eine Zuordnung für den Ausdruck, um eine entsprechende SQL-Anweisung zu generieren). Ich kann es nicht alles im Kommentar erklären, hoffe aber, OP wird den Kern bekommen. – vendettamit

+0

@vendetttamit Haben Sie irgendwelche Tipps, wie Sie die Erweiterungsmethode umgestalten können, damit dies funktioniert? – Justin

Antwort

1

Ich konnte es durch Trennen der Anrufe zur Arbeit bringen. Dies machte es auch leichter zu lesen!

public static IQueryable<T> WhereEquals<T>(this IQueryable<T> source, Func<T, string> expression, string queryParam) 
    { 
     if (string.IsNullOrWhiteSpace(queryParam)) 
     { 
      return source; 
     } 

     return source.Where(x => expression(x).Trim().ToLower() == queryParam.Trim().ToLower()); 
    } 

Vielen Dank an alle für Ihre Hilfe!