Ich habe eine Datenbanktabelle Item
und greife mit linq-to-sql darauf zu
Ich kann eine benutzerdefinierte Methode IsSpecial () für Items definieren, die true zurückgibt, wenn die Quadratwurzel von Item.id gerade ist:
%Vor%Dann kann ich diese Eigenschaft in einer linq-to-sql-Abfrage wie folgt verwenden:
%Vor%Aus ästhetischen Gründen möchte ich IsSpecial nichtstatisch machen und modifizieren, damit ich es so nennen kann:
%Vor%Idealerweise würde dies auch das Kombinieren von Anweisungen ermöglichen, was der obige (funktionierende) snytax nicht zulässt:
%Vor%Was ist die korrekte Syntax für die Definition dieser Methode?
Das funktioniert nicht:
%Vor%Bearbeiten: Ich fange an zu vermuten, dass ich nach etwas frage, was die Syntax einfach nicht erlaubt
Ich denke, ich kann mit datacontext.Item.Where(Item.IsSpecial).Where(i => i>100)
%Vor%
Vorschlag: Fügen Sie das readonly
Schlüsselwort hinzu.
Dann kann ich diese Eigenschaft in einer linq-to-sql-Abfrage wie folgt verwenden:
%Vor%
Richtig, denn Where
akzeptiert einen Parameter vom Typ Expression<Func<Item, bool>>
, der Item.IsSpecial
ist.
Aus ästhetischen Gründen möchte ich IsSpecial nichtstatisch machen und modifizieren, damit ich es so nennen kann:
%Vor%
Der Grund, warum dies nicht funktioniert, ist, weil IsSpecial
keine Funktion ist, sondern ein Ausdrucksbaum. ()
kann nur auf Funktionen angewendet werden. Ein Ausdrucksbaum beschreibt eine Funktion, ist aber keine Funktion. Sie können eine echte Funktion mit expression.Compile()
erstellen:
Dies wird jedoch nicht funktionieren, weil wieder Where
eine Ausdrucksbaumstruktur übergeben wird und IsSpecial.Compile()
nicht tatsächlich aufgerufen wird. LINQ to SQL versucht, es in SQL zu konvertieren, schlägt fehl, weil es Expression.Compile
nicht erkennt und eine Ausnahme auslöst.
Wenn Sie jedoch (IsSpecial.Compile())
ersetzen könnten, bevor LINQ to SQL es sehen würde ...
Hier kommt LINQKit ins Spiel:
Es bietet nur ein bisschen die Manipulation des Ausdrucksbaums, damit es funktioniert.
%Vor% Der .AsExpandable()
erstellt einen Wrapper um datacontext.Item
, um den Ausdruck vorzufiltern.
Idealerweise würde dies auch das Kombinieren von Anweisungen ermöglichen, was der obige (funktionierende) snytax nicht zulässt:
%Vor%
Kein Problem:
%Vor% Versuchen Sie, die Zuweisung zu IsSpecial in einem Konstruktor zu platzieren und alle anderen Konstruktoren an sie delegieren zu lassen, oder verwenden Sie eine partielle Methode wie OnCreated, um den Ausdruck IsSpecial zuzuweisen.
Innerhalb von partial class Item
Dadurch wird immer IsSpecial zugewiesen und der Zugriff auf "this" ermöglicht.
Tags und Links c# linq lambda linq-to-sql expression-trees