Ich versuche, eine dynamische Suche nach verschachtelten Objekten zu erstellen, die später an EF und SQL Server gesendet werden. Bisher kann ich nach allen Eigenschaften des ersten Objekts suchen. Hier ist eine sehr vereinfachte Version:
%Vor% Wenn propName = "Name"
alles in Ordnung ist, aber wenn propName = "Address.City"
ist, ist propertyInfo
null und ich erhalte diesen Fehler in der member
-Zuweisungszeile:
System.ArgumentNullException: Wert darf nicht null sein
Ich konnte die propertyInfo
der verschachtelten Eigenschaft mit der Lösung von diesem antworten :
Aber dann bekomme ich diesen Fehler bei member
Zuweisung:
System.ArgumentException: Die Eigenschaft 'System.String City' ist nicht für den Typ 'Benutzer'
definiert
Dies sollte auf Address
anstelle von User
zeigen, aber ich weiß nicht, ob ich hier richtig liege, ich meine, sollte ich parameterExpression
jetzt ändern?
Wie kann ich eine dynamische Suche nach verschachtelten Objekten durchführen, so dass dies in einen Lambda-Ausdruck umgewandelt und später an SQL gesendet werden kann?
Nach Kobis Rat und viel Versuch und Irrtum habe ich endlich funktioniert. Dies verwendet den Universal PredicateBuilder . Hier ist es:
%Vor%Warnung im Voraus - Ich baue den Ausdruck nicht, sondern prüfe nur seine Struktur.
Wenn ich Ausdrücke dynamisch erstellen muss, finde ich es nützlich, einen Ausdruck zu untersuchen und seine Struktur zu kopieren:
%Vor%Jetzt können Sie es einfach debuggen, zum Beispiel im unmittelbaren Fenster ( ctrl alt i hier):
%Vor% Hier sehen wir getCity
ist ein Lambda
mit einem Parameter. Lassen Sie uns den Körper untersuchen:
getCity.Body
ist ein Mitgliederzugriff - es greift auf das Mitglied City
des Ausdrucks user.Address
zu. Technisch gesehen ist das ein PropertyExpression
, was eine interne Klasse ist wir können es nicht einmal tun, aber das ist in Ordnung.
Schauen wir uns schließlich diesen inneren Ausdruck an:
Das ist nur user.Address
.
Jetzt können wir einen identischen Ausdruck erstellen:
%Vor% Expression.MakeMemberAccess
funktioniert auch, anstatt Expression.Property
.
Offensichtlich müssten Sie Ihren Ausdruck in einer Schleife und dynamischer erstellen, aber die Struktur ist die gleiche.
Es könnte sich lohnen, einen Blick auf Linqkits Prädikat-Builder zu werfen ...
Ich würde auch Entity SQL betrachten ...
Sie könnten ein Rad mit dem Code, den Sie schreiben, neu erfinden.
Auch sollte ich kommentieren, in Bezug auf die SQL Server-Plan-Caching, es sei denn, Sie haben keine andere Wahl, ich würde nicht dynamisch Abfragen erstellen. Sie erstellen besser eine einzelne Abfrage, die alle Ihre Fälle behandelt, für die SQL Server einen Plan zwischenspeichern kann. Ihre Abfragen werden viel langsamer ausgeführt, wenn bei der Ausführung jedes Plans im Plancache von SQL Server kein Plan angezeigt wird.
Tags und Links c# entity-framework lambda reflection