I tipi di cogliere il tutto in ritardo concetto di esecuzione, ma le seguenti ha mi ha sconcertato ...Slow foreach() su una query LINQ - ToList() aumenta enormemente le prestazioni: perché?
Su un DataTable contenente circa 1000 righe, io chiamo AsEnumerable(). Quindi seleziono le entità restituite in un IEnumerable di classi fortemente tipizzate (1) ... Ecco dove mi confondo: eseguo un ciclo foreach sulla raccolta; selezionando le cose dai singoli elementi della collezione utilizzando un gruppo di Dove() chiamate (2) ... Ed è lento.
DataTable.AsEnumerable().Select(r => new ObjectRepresentation { ... });
item.Where(i => i.SomeEnum == SomeEnum.Something)
... Ma se io chiamo ToList() subito dopo il mio AsEnumerable() chiamata sul DataTable, il foreach il ciclo richiede meno di un secondo per essere completato.
Cosa mi manca qui? Sto effettivamente chiamando AsEnumerable() ogni volta che il mio ciclo itera? O ogni volta che accedo a un articolo nella collezione? O ogni volta che eseguo una chiamata Dove() su un articolo nella raccolta? O tutto quanto sopra?
Aggiornamento
codice Un po 'completo:
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
}
Sembra che si stia eseguendo una chiamata al database a ogni iterazione. È possibile eseguire SQL Profiler per vedere se è vero ... –
Perché chiamare AsEnumerable()? AsEnumerable modifica un oggetto in fase di compilazione a IEnumerable se implementa già IEnumerable . Perché non iterare le righe utilizzando la proprietà Rows di una tabella? –
Wix
@Wix: 'DataTable' non implementa già' IEnumerable '. Quando chiami 'AsEnumerable' su un' DataTable' stai chiamando il metodo 'DataTableExtensions.AsEnumerable', * not *' Enumerable.AsEnumerable'. http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.asenumerable.aspx –
LukeH