2009-08-10 12 views
5

Was Unterschied zwischen diesen beiden Aussagen ist:LINQ: Differenz zwischen 'c Wählen Sie' und 'neu auswählen (c ...'

var result = from c in context.CustomerEntities 
join p in context.ProjectEntities on c.Pk equals p.CustomerPk 
where p.Entered > DateTime.Now.AddDays(-15) 
select c; 

und

var result = from c in context.CustomerEntities 
join p in context.ProjectEntities on c.Pk equals p.CustomerPk 
where p.Entered > DateTime.Now.AddDays(-15) 
select new (c.Company, c.Entered, c.pk); 

Gibt es eine leistungsbezogene Problem in diesen Aussagen. (Der Einfachheit halber c enthält nur diese 3 coloums.)

Dank.

Antwort

10

Was ist der Unterschied zwischen diesen beiden Anweisungen

Die ersten Gibt eine gefilterte Sequenz des ursprünglichen/vollständige Quellenobjekt; die zweite macht noch den Filter, aber gibt eine Sequenz eines anonymen Typs mit nur diese drei Eigenschaften zurück.

Gibt es ein leistungsbezogene Problem in diesen Aussagen

Leistung auf dem Back-End abhängt. Wenn dies LINQ-to-Objects ist, erstellen Sie mit zusätzliche Objekte (anonyme Typen) pro Datensatz, so dass möglicherweise ein sehr geringer Aufwand entsteht. Wenn dies jedoch LINQ-to-SQL usw. (ein Datenbank-Back-End) ist, kann dies eine große Vorteil sein. Der Abfrage-Generator prüft, welche Spalten benötigt werden und holt nur die drei in Ihrem anon-Typ; Wenn Sie zum Beispiel ein BLOB (oder einfach nur lang varchar) in Ihren Daten haben, die Sie nicht benötigen, kann dies ein riesiger Vorteil sein.

Zusätzliche Hinweise: Sie können nicht anonyme Typen in der Signatur einer Methode enthalten, so dass Sie vielleicht finden Sie Ihre eigene DTO Art müssen für diesen Zweck erklären:

return new CustomerDto { Company = c.Company, Entered = c.Entered, PK = c.pk}; 
... 
public class CustomerDto { ... } 
+1

+1 für die generische Antwort, aber in seiner Situation gibt er sowieso alle Spalten zurück. – cjk

+0

Ja ck ist korrekt Ich gebe alle Spalten zurück. – Waheed

1

im Zweifelsfall Profil.

Aber ja, ich denke, dass es einen Leistungsoverhead gibt. Wenn Sie select c tun, dann enthält die Sammlung Verweise auf die ursprünglichen Elemente. Wenn Sie select new { ... } tun, erstellt C# einen anonymen Typ für Sie, erstellt neue Instanzen dieses Typs und füllt sie mit Daten. Klingt definitiv langsamer für mich.

+0

+1 für die Empfehlung Profilerstellung. – Marcel

2

Der Hauptunterschied besteht darin, dass das erste Beispiel Verweise auf vorhandene Instanzen zurückgibt, während das zweite Beispiel neue Instanzen eines anonymen Typs erstellt. Ich wäre mehr mit diesem Thema beschäftigt als mit möglichen Leistungsproblemen.

2

ich einige Tests lief (mit Stoppuhr). In keinem Fall waren anonyme Typen schneller, in Linq-to-SQL (gegen SQL Server), Linq-to-Entities (gegen MySQL) und Linq-to-Objects (gegen eine Liste). Tatsächlich war es normalerweise langsamer, abhängig davon, wie viele Spalten Sie auswählen.

Eines meiner Ergebnisse: Ich führte jede Abfrage 5000 mal gegen eine 5-Spalte-Tabelle mit 400 Zeilen mit Linq-to-Entities bestückt.

anonymes Objekt (Auswahl 1 Spalte): 17314ms

anonymes Objekt (Auswahl 5 Spalten): 19193ms

Quellobjekt: 16055ms

Wie auch immer, der beste Weg, es herauszufinden, zu prüfen ist selbst (dauert ungefähr die Zeit, um einen guten Beitrag zu schreiben).

Verwandte Themen