Dynamische Lambda-Suche in IQueryable für verschachtelte Objekte erstellen

8

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 :

%Vor%

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?

    
Marcos Dimitrio 27.07.2015, 05:16
quelle

3 Antworten

3

Nach Kobis Rat und viel Versuch und Irrtum habe ich endlich funktioniert. Dies verwendet den Universal PredicateBuilder . Hier ist es:

%Vor%     
Marcos Dimitrio 28.07.2015, 04:32
quelle
1

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:

%Vor%

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:

%Vor%

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.

    
Kobi 27.07.2015 06:05
quelle
0

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.

    
Mick 27.07.2015 05:44
quelle