Ich finde etwas unerwartetes Verhalten, wenn Sie eine Projektion in einer LINQ to SQL-Abfrage mit einem Func verwenden. Beispielcode erklärt besser als Worte.LINQ to SQL-Projektion: Func vs Inline
Eine grundlegende L2S lambda Abfrage mit Projektion:
db.Entities.Select(e => new DTO(e.Value));
auf die gewünschte SQL übersetzt:
SELECT [t1].[Value]
FROM [Entity] AS [t1]
jedoch, wenn der Vorsprung in eine Func wie folgt gesetzt wird:
Func<Entity, DTO> ToDTO = (e) => new DTO(e.Value);
Und so genannt:
db.Entities.Select(e => ToDTO(e));
Die SQL jetzt zieht wieder alle Spalten in der Tabelle, nicht nur die, die in der Projektion:
SELECT [t1].[Id], [t1].[Value], [t1].[timestamp], [t1].[etc...]
FROM [Entity] AS [t1]
Also meine Frage ist, wie kapseln ich diese Projektion ohne die LINQ to SQL die ganze Entität instanziieren?
Dinge zu beachten, die DTO, die ich verwende, hat einen geschützten Standardkonstruktor, so dass ich einen Objektinitialisierer nicht verwenden kann. Und da die DTO-Klasse nicht geändert werden kann, müsste ich eine Unterklasse erstellen, um dieses Verhalten zu implementieren. Was ist in Ordnung, wenn das die einzige Lösung ist.
Danke.
Bearbeiten:
Danke an Brian für die Lösung. Ich hatte vorher einen Ausdruck versucht, konnte aber die Syntax nicht herausfinden. Hier ist der Arbeitscode:
Expression<Entity, DTO> ToDTO = (e) => new DTO(e.Value);
Dann rufen Sie es wie folgt aus:
db.Entities.Select(ToDTO);
Zuerst versuchte ich es so zu nennen, die nicht kompiliert werden würde. Dies ist die richtige Syntax zum Aufrufen eines Func, aber kein Ausdruck.
db.Entities.Select(e => ToDTO(e));
Wie rufe ich es auf? Ich habe das versucht, konnte aber den Code nicht kompilieren. – mikesigs
Okay, ich habe es zur Arbeit gebracht. Nicht, wie ich erwartet hatte, der Code würde aussehen. Aber es hat perfekt funktioniert, danke! – mikesigs
wie * DID * Sie es aufrufen ???! :-D –