2011-06-09 11 views

Respuesta

10

Con el fin de contar con eficacia el número de entradas, el marco tiene que evaluar la consulta, golpeando así la base de datos. Sin embargo, debido a que la consulta puede haber cambiado entre Count() y ToList(), debe evaluar nuevamente. Considere lo siguiente:

var myIQueryable = my.db<SomeModel>(); // IQueryable<SomeModel> 
var countQuery = myIQueryable.Count(); // 10 
MakeAdditions(myIQueryable, 10);  // adds 10 items 
var list = myIQueryable.ToList();  // List<SomeModel> count=20 
MakeAdditions(myIQueryable, 10); 
var countList = list.Count();   // still 20, List never changed 

Dicho de otra manera, todas las llamadas en contra IQueryable todavía están sujetos a la forma en que se ejecuta sus consultas. Después de capturar una consulta en una lista, se trata exclusivamente de su lista en memoria, independientemente de los cambios que se produzcan en la fuente de datos de IQueryable.

+0

lo tanto, incluso si usted está haciendo adiciones en el mismo IQueryable evaluado, añadiendo un filtro para Por ejemplo, IQueryable no usa su resultado anterior? – dmorganb

+2

Exactamente, la naturaleza de IQueryable es evacuar la consulta cuando se invoca. Si desea utilizar una evaluación previa, primero debe capturarla. 'var list = myIQueryable. ToList(); MakeAdditions(); var count = list.Count(); ' – max

+0

Si no está buscando, también puede obtener los resultados con ToList, luego use su propiedad Count para no golpear la base de datos dos veces Por otro lado, si está buscando datos, entonces su lista tendrá menos resultados que el recuento, por lo que tendría que hacer dos visitas separadas en e base de datos. Me pregunto, sin embargo, si hay algún aumento en el rendimiento al llamar a Count y luego ejecutar la consulta (paginada), vs ejecutar la consulta (paginada) y luego llamar a Count. ¿De alguna manera se almacenan en caché los resultados o planes que serían útiles? – Triynko

5

Sí, golpea la base de datos dos veces, ya que tanto Count como ToList se evalúan con entusiasmo. Si lo que desea es acceder a él una vez, haga lo siguiente:

var list = myIQueryable.ToList(); 
var count = list.Count; 
+0

Me golpearon por 30 seg :( –

+0

Gracias, que va a hacer. – dmorganb

+0

acepté la respuesta de Maxwell porque tiene un poco más de detalle sobre el mismo – dmorganb

Cuestiones relacionadas