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.
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 .:
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.QuotationToExpression
, 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:
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:
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.)