In meinem C # -Code habe ich zwei WHERE-Abfragen, von denen ich beide auf ein IQueryable zugreifen kann und die ganze Sache auf SQL kompiliert haben, und beide haben eine Menge gemeinsamer Logik.
Ich glaube, das ist KEINE Duplizierung dieser ähnlichen Frage: Verwendung der Funktion in Select-Klausel der Entity Framework-Abfrage , weil in meinem Szenario kann die fragliche Funktion in SQL konvertiert werden - EF merkt einfach nicht, dass es das kann.
Die Abfragen sind ungefähr:
%Vor%AND
%Vor%Also eine grundlegende BusinessLogic-Regel für "besitzt eine Vorlage" und dann eine Folge davon für "besitzt DataReturn, wenn Firma mit Vorlage übereinstimmt"
Wie Sie sehen können, denken Sie nur an die C #, diese könnten leicht umstrukturiert werden als:
%Vor%So reduzieren Sie die Duplizierung (Yay!)
Aber dann wird sich EF beschweren, dass es nicht weiß, was es mit UserOwnsTemplate
machen soll, trotz der Tatsache, dass es die Logik in SQL perfekt verarbeiten kann.
AFAICT gibt es keinen schönen Weg, dies zu lösen. Ich denke, meine Optionen sind:
UserOwnsTemplate
in eine UDF, eine in der Datenbank definierte SQL-Funktion.
Expression<Func<Template,bool>>
, das UserOwnsTemplate
definiert, als Variable zu, und erstellen Sie dann relevante Expression<Func<DataReturn ,bool>>
für die DataReturn-Version von Hand mit Expression.AndAlso
, um die beiden "Klauseln" zusammen zu kleben.
Kann jemand andere verfügbare Optionen sehen?
Kann ich etwas tun, um EF zu zwingen, die Funktion in SQL zu analysieren? (Der Begriff "Inling" kommt mir in den Sinn, aber ich weiß nicht 100%, was ich damit meine?)
Kann jemand eine Möglichkeit sehen, ret.Request.Template in ein IQueryable umzuwandeln, so dass ich einfach die andere WhereIsOwnedBy-Erweiterungsmethode darauf aufrufen kann?
Irgendwelche anderen Vorschläge überhaupt?
Sie können Ihre Syntax beibehalten und es funktionieren lassen, aber Sie müssen eine zusätzliche Methode für das äußere IQueryable & lt; & gt;.
aufrufenDer Trick besteht darin, die IQueryable & lt; & gt; .Expression manuell durch eine Kopie zu ersetzen, in der Sie den Funktionsaufruf durch den entsprechenden Ausdruck & gt; ersetzen.
Die Idee ist also, so etwas zu tun:
%Vor%Und dann können Sie das tun:
%Vor%Das Problem ist, dass Ihre Methode Teil der Ausdrucksbaumstruktur wird und dass EF sie nicht auswerten kann. Grundsätzlich ist es möglich, Teile des Ausdrucksbaums auszuwerten, bevor die Abfrage ausgelöst wird. Sehen Sie sich Re-Linq an: Ссылка Es hat eine Klasse PartialEvaluatingExpressionTreeVisitor, die alle partiellen Ausdrucksbäume auswerten kann, dh es wird Ihre Methode finden, werten Sie es aus und injizieren Sie den eigentlichen Ausdrucksbaum. Dies wird zu bestimmten Kosten für die Leistung kommen, aber es kann nicht signifikant sein, und Sie müssen sauberes Design im Vergleich zu Leistung messen.
Tags und Links sql-server c# entity-framework function