Execution-Deferred IQueryableT von Dynamic Linq?

9

Ich verwende Dynamic Linq , um einige Abfragen auszuführen (tut mir leid, aber es ist meine einzige Option). Als Ergebnis erhalte ich IQueryable anstelle von IQueryable<T> . In meinem Fall möchte ich ein IQueryable<Thing> , wobei Thing ein konkreter Typ ist.

Meine Abfrage ist so:

%Vor%

Mein Ding.cs:

%Vor%

Ja, ich weiß, dass das genaue obige Ding ohne Dynamic Linq gemacht werden kann, aber ich habe etwas Variabilität, die ich hier vereinfacht habe. Ich kann es mit meiner Variabilität arbeiten lassen, wenn mein Rückgabetyp einfach IQueryable ist, aber ich kann nicht herausfinden, wie ich in IQueryable<Thing> umwandeln kann, während ich die Ausführung verzögere und Entity Framework weiterhin glücklich halte. Ich habe die dynamische Select immer etwas zurückgeben (mit den richtigen Daten), dass wie folgt aussieht a Thing . Aber ich kann mir einfach nicht vorstellen, wie man IQueryable<Thing> zurückgibt und könnte dort Hilfe gebrauchen. Danke !!

Fehlgeschlagener Versuch 1

Basierend auf dem Vorschlag von Rex M versuche ich jetzt, AutoMapper zu verwenden, um dieses Problem zu lösen (obwohl ich mich diesem Ansatz nicht verschrieben habe und bereit bin, andere Ansätze zu versuchen). Für den AutoMapper-Ansatz mache ich das so:

%Vor%

Aber dies führt zu einer InvalidOperationException:

  

Fehlende Karte von DynamicClass2 zu Thing. Erstellen Sie mit Mapper.CreateMap.

Die Sache ist, während ich Thing definiert habe, habe ich DynamicClass2 nicht definiert und kann sie daher nicht zuordnen.

Fehlgeschlagener Versuch 2

%Vor%

Dies ergibt eine InvalidCastException und scheint das gleiche zugrundeliegende Problem zu sein, das der oben genannte AutoMapper schlägt:

  

Das Objekt vom Typ 'System.Data.Entity.Infrastructure.DbQuery'1 [DynamicClass2]' konnte nicht in den Typ 'System.Linq.IQueryable'1 [MyDtos.Thing]' umgewandelt werden.

    
Jaxidian 04.12.2015, 22:06
quelle

4 Antworten

1

Wenn ich das richtig verstehe, sollte die folgende Erweiterungsmethode die Aufgabe für Sie erledigen.

%Vor%

(Randnotiz: Ehrlich gesagt habe ich keine Ahnung, wofür das values -Argument ist, aber es wurde hinzugefügt, um der entsprechenden DynamicQueryable.Select -Methodensignatur zu entsprechen.)

Also wird Ihr Beispiel so etwas werden

%Vor%

Wie es funktioniert

Die Idee ist ziemlich einfach.

Die Select Methodenimplementierung in DynamicQueryable sieht ungefähr so ​​aus

%Vor%

Es wird ein Selektionsausdruck dynamisch erstellt und an die Methode Select der Quelle gebunden. Wir gehen genau so vor, aber nachdem wir den vom DynamicExpression.ParseLambda -Aufruf erzeugten Selektor-Ausdruck geändert haben.

Die einzige Voraussetzung ist, dass die Projektion die Syntax "new (...)" verwendet und die Namen und Typen der projizierten Eigenschaften übereinstimmen, was meiner Meinung nach in Ihren Anwendungsfall passt.

Der zurückgegebene Ausdruck ist ungefähr so ​​

%Vor%

wobei TargetClass eine dynamisch generierte Klasse ist.

Alles was wir wollen ist, den Quellenteil beizubehalten und nur diese Zielklasse / Eigenschaften durch die gewünschte Klasse / Eigenschaften zu ersetzen.

Wie bei der Implementierung werden zuerst die Eigenschaftszuweisungen mit

konvertiert %Vor%

und dann wird new DynamicClassXXX { ... } durch

ersetzt %Vor%     
Ivan Stoev 12.12.2015, 18:18
quelle
4

Sie können die AutoMapper Queryable Extensions verwenden, um ein IQueryable zu erstellen, das das zugrunde liegende IQueryable umschließt und so das Original IQueryable's IQueryProvider und die verzögerte Ausführung, fügt aber eine Mapping / Translation-Komponente in die Pipeline ein, um von einem Typ in einen anderen zu konvertieren.

Es gibt auch AutoMapper's UseAsDataSource , was einige häufige Szenarien für die Abfrageerweiterung vereinfacht. p>     

Rex M 04.12.2015 22:33
quelle
0

Wäre so etwas für Sie von Vorteil?

%Vor%

Vielleicht möchten Sie sich das Generic Search-Projekt auf Github hier ansehen: Ссылка

    
Anthony Hart 10.12.2015 00:31
quelle
-1

Dynamic Linq ist in diesem Fall nicht erforderlich.

%Vor%     
hazimdikenli 09.12.2015 14:44
quelle