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.IEnumerable1[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.
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.
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.
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.
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.
Tags und Links c# lambda expression visitor