2011-01-13 14 views
4

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)); 

Antwort

5

Sie müssen wahrscheinlich ein Expression, nicht ein Func

Expression<Func<Entity, DTO>> ToDTO = (e) => new DTO(e.Value); 

IQueryable Erweiterungsmethoden arbeiten mit Expression s, nicht Func s

Indem in einem Func erstellen, sind Sie wahrscheinlich Aufruf die Erweiterungsmethode IEnumerable, weshalb Linq2Sql so funktioniert, wie es ist.

+0

Wie rufe ich es auf? Ich habe das versucht, konnte aber den Code nicht kompilieren. – mikesigs

+0

Okay, ich habe es zur Arbeit gebracht. Nicht, wie ich erwartet hatte, der Code würde aussehen. Aber es hat perfekt funktioniert, danke! – mikesigs

+0

wie * DID * Sie es aufrufen ???! :-D –