I der Art die ganze erfassen Ausführung Konzept verzögert, aber die folgenden Dokumente verwirrt mich ...Langsam foreach() auf einer LINQ-Abfrage - ToList() steigert die Leistung immens - warum ist das?
Auf einer Datentabelle etwa 1000 Zeilen enthält, nenne ich AsEnumerable(). Ich wähle dann die in einem IEnumerable stark typisierten Klassen zurückgegebene Entitäten (1) ... Hier ist, wo ich verwirrt bin: Ich mache eine foreach-Schleife auf die Sammlung; Auswahl von Sachen aus den einzelnen Artikeln in der Sammlung mit einer Reihe von Where() Anrufe (2) ... Und es ist tot langsam.
DataTable.AsEnumerable().Select(r => new ObjectRepresentation { ... });
item.Where(i => i.SomeEnum == SomeEnum.Something)
... Aber wenn ich ToList() aufrufen gleich nach meinem AsEnumerable() Anruf auf dem Datatable, die foreach Die Schleife dauert weniger als eine Sekunde.
Was fehlt mir hier? Rufe ich effektiv AsEnumerable() jedes Mal, wenn meine Schleife iteriert? Oder jedes Mal, wenn ich auf ein Objekt in der Sammlung zugreife? Oder jedes Mal, wenn ich eine Where() Anruf auf ein Element in der Sammlung machen? Oder alles oben genannte?
aktualisieren
Etwas vollständige Code:
public class ObjectRepresentation
{
public SomeEnum SomeEnum { get; set; }
}
var collection = DataTable.AsEnumerable().Select(r => new ObjectRepresentation
{
SomeEnum = (SomeEnum)Convert.ToInt32(r["SomeEnum"])
});
foreach(var item in collection) // slow loop
{
// 10 or so Where() calls on item inside this loop
}
collection = collection.ToList(); // Hit hyper speed button!
foreach(var item in collection) // fast loop
{
// 10 or so Where() calls on item inside this loop
}
Klingt so, als würden Sie bei jeder Iteration einen Datenbankaufruf ausführen. Sie könnten den SQL Profiler ausführen, um zu sehen, ob das wahr ist ... –
Warum AsEnumerable() aufrufen? AsEnumerable ändert ein Objekt zur Kompilierzeit in IEnumerable, wenn es bereits IEnumerable implementiert. Warum iterieren Sie die Zeilen nicht mithilfe der Rows-Eigenschaft einer Tabelle? –
Wix
@Wix: 'DataTable' implementiert 'IEnumerable' nicht bereits. Wenn Sie 'AsEnumerable' auf einer' DataTable' aufrufen, rufen Sie die 'DataTableExtensions.AsEnumerable' Methode auf, * nicht *' Enumerable.AsEnumerable'. http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.asenumerable.aspx –
LukeH