ExpressionFuncT, bool aus einer F # -Funktion

8

in linq,. Wo nimmt ein Ausdruck & gt; Prädikat, das ich in F # als

schreiben kann %Vor%

Ich benutze FSharp.Powerpack, um den Ausdruck aus einem Zitat zu erstellen, aber was es mir gibt, ist ein MethodCallExpression. Wenn man genauer hinschaut, baut der Powerpack-Code das Lambda korrekt auf, wickelt es jedoch in einen Convert-Aufruf (warum ist das so?). Ich frage mich, ob das Argument zum Methodenaufruf (ein Lambda) schließlich den Ausdruck & gt; Ich brauche.

Also die Frage ist, warum der Convert-Aufruf und wie man das Lambda tatsächlich mit der Func-Signatur bekommt.

    
hammett 03.02.2012, 19:36
quelle

2 Antworten

12

Ich kann mich nicht mehr erinnern, wo ich dieses bisschen Code gefunden habe, aber das ist es, was ich benutze, um Expr<'a -> 'b> in Expression<Func<'a, 'b>> zu konvertieren. Hoffentlich löst das dein Problem.

%Vor%     
Daniel 03.02.2012, 20:26
quelle
5

Eine Möglichkeit, dies zu tun, besteht darin, die Tatsache zu nutzen, dass F # diese Konvertierung automatisch ausführt, wenn Methoden auf .NET-Typen aufgerufen werden, die ein Expression<Func<...>> erwarten.

Ich bin mir nicht ganz sicher, wann dies zur Sprache hinzugefügt wurde, aber mit F # 4 müssen Sie F # -Ausdrücke nicht explizit in LINQ-Ausdrücke konvertieren. Wenn der Grund, warum Sie das überhaupt machen wollten, darin bestand, IQueryable LINQ-APIs (oder andere ausdrucksbasierte .NET-APIs) zu verwenden, dann funktioniert es jetzt einfach und ohne Aufwand, z. B .:

%Vor%

funktioniert einfach. Obwohl dies wie ein gewöhnliches Lambda aussieht (wir haben die Ausdruckssyntax von F # nicht verwendet), kompiliert dies Code, der ein F # -Expressionsobjekt erzeugt, und übergibt dieses dann an LeafExpressionConverter‌​.QuotationToExpressi‌on , um es in ein LINQ-Expressionsobjekt umzuwandeln.

Aber manchmal möchten Sie das Expression-Objekt im LINQ-Stil direkt in F # finden. (Z. B. ist es manchmal nützlich, eine F # -Funktion zu schreiben, die einen Ausdruck erzeugt, den Sie in mehreren Abfragen verwenden.) In diesem Fall können Sie einen Helfer wie diesen schreiben:

%Vor%

Das sieht so aus, als ob es nichts bringt - es gibt nur sein Argument zurück. Da FunAs jedoch ein .NET-Typ ist, kompiliert F # jede Aufrufwebsite, die dies aufruft, automatisch mit einem fun -Ausdruck in Code, der einen geeigneten LINQ-Abfrageausdruck generiert. Zum Beispiel:

%Vor%

Hier wird linqExpr vom Typ Expression<Func<MyEntity, bool>> sein.

Der Schlüssel dazu ist, dass diese Methode ein Mitglied eines .NET-Typs ist. Wenn Sie genau das gleiche mit einer normalen F # -Funktion versuchen:

%Vor%

was genau so aussieht wie FunAs.LinqExpression , Sie werden feststellen, dass Sie es nicht so nennen können. Zum Beispiel, wenn Sie dies versuchen:

%Vor%

Sie erhalten einen (wenig hilfreichen) Fehler: 'Diese Funktion benötigt zu viele Argumente oder wird in einem Kontext verwendet, in dem eine Funktion nicht erwartet wird'.

Wenn Sie diese Funktion als Mitglied eines .NET-Typs verwenden, können wir die hilfreiche Funktion von F # "Sie scheinen eine .NET-API aufzurufen, die einen Ausdruck im LINQ-Stil erwartet, lassen Sie mich das für Sie erledigen" verwenden .

(Es ist möglich, dass es eine explizitere Möglichkeit gibt, den LINQ-Compiler aufzufordern, denselben Trick für Sie auszuführen, ohne einen .NET-Typ in das Bild zu bringen, aber ich habe ihn nicht gefunden.)

    
Ian Griffiths 17.03.2017 13:19
quelle

Tags und Links