Problemumgehungen für die Verwendung von benutzerdefinierten Methoden/extension Methoden in LINQ to Entities
Ich habe eine GenericRepository Klasse, die die db-Interaktion.
protected GenericRepository rep = new GenericRepository();
Und in meine BLL-Klassen, kann ich die Abfrage der db wie:
public List<Album> GetVisibleAlbums(int accessLevel)
{
return rep.Find<Album>(a => a.AccessLevel.BinaryAnd(accessLevel)).ToList();
}
BinaryAnd ist eine Erweiterung Methode, die prüft, zwei int-Werte bit für bit. z.B. AccessLevel=5
=> AccessLevel.BinaryAnd(5)
und AccessLevel.binaryAnd(1)
beide true zurück.
Allerdings kann ich nicht mit dieser Erweiterung Methode in meiner LINQ-Abfragen. Ich bekomme einen runtime error wie folgt:
LINQ to Entities does not recognize the method 'Boolean BinaryAnd(System.Object, System.Object)' method, and this method cannot be translated into a store expression.
Habe auch versucht es zu ändern, um eine benutzerdefinierte Methode, aber kein Glück. Was sind die workarounds?
Sollte ich alle Alben und dann iterieren Sie durch eine foreach-Schleife und wählen Sie jene, die mit dem AccessLevels?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kann man nur den Kern der Erweiterung Methoden und CLR-Methoden definiert, die für Ihre EF-Anbieter bei der Verwendung von Entity Framework und Abfragen auf
IQueryable<T>
. Dies ist, weil die Abfrage übersetzt wird direkt in SQL-code und die auf dem server ausgeführt.Können Sie stream die komplette Kollektion (mit
.ToEnumerable()
) Abfragen dann das lokal, oder wandeln diese in eine Methode, die übersetzbar ist direkt zu SQL von Ihrem provider.Dass gesagt wird, basic bitweise Operationen werden unterstützt:
So, wenn Sie diese umschreiben nicht verwenden eine Methode, und nur noch die bitweise operation auf den Wert direkt an, es sollte funktionieren, wie gebraucht. Versuchen Sie etwas wie die folgenden:
(Ich bin mir nicht ganz sicher, wie Ihre aktuelle Erweiterung Methode funktioniert - das würde überprüfen, um zu sehen, wenn eine der Flaggen wieder kommen wahr, und das scheint passend zu Ihrer Aussage...)
Merke ich, dass es bereits eine akzeptierte Antwort, ich dachte, ich würde post dies für den Fall, jemand wollte versuchen, schriftlich eine LINQ-Ausdruck interceptor.
Also... hier ist, was ich getan habe, um übersetzbar benutzerdefinierte Erweiterung Methoden: Code-Beispiel
Ich glaube nicht, dass diese zu einer fertigen Lösung, aber es sollte hoffentlich ein guter Ausgangspunkt für alle, die mutig genug, um es bis zur Fertigstellung.
.Where(p=> p.Key == 25)
gibt eine Fehlermeldung über p als ungebunden. Also ich hatte zu erklären, die lambda wie dieseExpression<Func<PropertyHistory, bool>> exp = (p) => p.Key ==25;
und verwenden Sie dann in.Where(exp)
. Unter Berücksichtigung der Wiederverwendbarkeit der Erweiterung, es ist immer noch toll. Es ist ein open bounty hier, wenn Sie wollen, posten Sie Ihre Antwort. Ich würde Sie wirklich schätzen, posten Sie einen Kommentar, wenn Sie updates machen, um Ihren code. Das ist würdig, ein codeplex-Projekt, denke ich. stackoverflow.com/questions/10826275/...Gibt es Möglichkeiten zum ändern der linq-Abfrage nur, bevor EF übersetzt Sie in SQL, in diesem moment hätten Sie für die übersetzung Ihrer "ausländischen" - Methode in ein Konstrukt übersetzt von EF.
Sehen eine Vorherige Frage von mir Wie wrap Entity Framework abfangen der LINQ-Ausdruck unmittelbar vor der Ausführung? und mir EFWrappableFields Erweiterung, die nicht nur diese für verpackte Felder.