Ersetzen Sie den Parameter, um auf den geschachtelten Parameter im Lambda-Ausdruck zu zeigen

8

Ich kann einfache Parametertypen in einem Lambda-Ausdruck dank einiger Antworten auf einer vorherigen Frage erfolgreich ersetzen, aber ich kann nicht herausfinden heraus, wie man Parameter von einem eingehenden Lambda zu einem verschachtelten Parameter ersetzt.

Betrachten Sie die folgenden Objekte:

%Vor%

und ein Repository:

%Vor%

und schließlich ein Ausdruck Besucher, der das Prädikat in das richtige für die Dto-Modelle

konvertieren sollte %Vor%

Momentan bekomme ich die folgende Ausnahme

  

[System.ArgumentException: Ausdruck des Typs   'System.Collections.Generic.ICollection 1[ExpressionVisitorTests.DtoFavouriteColour]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable 1 [ExpressionVisitorTests.DomainPerson]'   der Methode 'Boolean   Beliebig [DomainPerson] (System.Collections.Generic.IEnumerable 1[ExpressionVisitorTests.DomainPerson], System.Func 2 [ExpressionVisitorTests.DomainPerson, System.Boolean]) ']

Hier ist eine dotnetfiddle Funktion, die nicht funktioniert.

Vielen Dank im Voraus für jede Hilfe.

    
Jake Aitchison 21.07.2016, 08:43
quelle

2 Antworten

4

Sie haben das konkrete Problem bereits gelöst, daher kann ich nicht sagen, ob das, was ich Ihnen vorschlagen werde, besser / eleganter ist, aber es ist sicherlich etwas allgemeiner (entfernte die konkreten Typen / Eigenschaften / Annahmen), kann daher für die Übersetzung ähnlicher Ausdrücke aus verschiedenen Modelltypen wiederverwendet werden.

Hier ist der Code:

%Vor%

und die Verwendung für Ihr konkretes Beispiel:

%Vor%

Wie Sie sehen, erlaubt es Ihnen, ein einfaches Mapping von einem Typ zum anderen zu definieren, und optional von einem Member eines Typs zu einem Member / Ausdruck eines anderen Typs (sobald sie kompatibel sind) mit "fließender" Syntax mit Lambda-Ausdrücke. Die Elemente, für die keine Zuordnung festgelegt wurde, werden anhand des Namens wie im ursprünglichen Code zugeordnet.

Sobald die Zuordnungen definiert sind, wird die eigentliche Verarbeitung des Kurses durch eine benutzerdefinierte ExpressionVisitor ähnlich der Ihren vorgenommen. Der Unterschied besteht darin, dass es ParameterExpression s nach type abbildet und konsolidiert und auch jede statische generische Methode übersetzt, also auch mit Queryable und ähnlichem funktionieren sollte.

    
Ivan Stoev 28.07.2016, 13:09
quelle
6

Nach einigem Suchen stieß ich auf diese Antwort von John Skeet , was dazu geführt hat, dass ich eine funktionierende Lösung gefunden habe, die ein Override für VisitMethodCall method auf ExpressionVisitor hinzufügt, um das ursprüngliche MethodInfo durch a zu ersetzen Neues für die richtige Art der Sammlung.

%Vor%

Ich musste auch sicherstellen, dass mein Verweis auf die _parameters -Auflistung nicht durch verschachtelte Aufrufe von VisitLambda<T> ersetzt wurde, was beim Besuch von node.Body passieren könnte.

%Vor%

Siehe dotnetfiddle für eine funktionierende Lösung.

Wenn jemand eine bessere / elegantere Lösung hat, füge bitte eine Antwort hinzu, die ich markieren kann.

    
Jake Aitchison 24.07.2016 16:12
quelle

Tags und Links