2012-06-05 8 views
6

Tengo curiosidad por saber en qué punto de la cadena de llamadas debe incluirse cuando se utiliza Entity Framework. Considere siguiente método:¿En qué parte de la cadena de llamadas debe estar incluida la extensión EF LINQ()?

// sample usage from service layer 
// _customerRepository.Paginate(1, out totalRecords, 25, "DateJoined DESC, AmountSpent", "DateJoined >= '2009-02-01'", "Invoices, Refunds"); 
public virtual IQueryable<T> Paginate(int page, out int total, int pageSize, string sort = "Id", string filter = null, string includes = null) 
{ 
    IQueryable<T> query = DatabaseSet; 

    total = query.Count(); // get total # of records (required for pagination)... 
    var skipTo = GetValidSkipCount(page, total, pageSize); 

    if (!String.IsNullOrWhiteSpace(filter)) 
    { 
     query.Where(filter); 
    } 
    // should includes be before filtering? 
    // should query.Count() be called after query.Include? 
    // does it matter? 
    if (!String.IsNullOrWhiteSpace(includes)) 
    { 
     query.IncludeMany(includes); // my own extension that takes comma separated string of entities to include 
    } 

    return query.OrderBy(sort).Skip(skipTo).Take(pageSize); 
} 

Mis preguntas son:

  1. debe incluir siempre estar por primera vez en la cadena de llamadas?
  2. ¿Count() se ve afectado por Include? Si es así, supongo que debo hacer el recuento después de incluir
  3. debe incluir ser antes o después del filtrado (dónde)?
  4. ¿realmente importa porque EF es lo suficientemente "inteligente" como para descubrirlo todo?

Respuesta

10

debe Incluir siempre ser el primero en la cadena de llamadas?

Include no tiene que ser el primero en la cadena. Include es un operador muy especial que no es parte de la consulta. Es como la expansión de la consulta. Tampoco es un operador LINQ: es el operador EF definido en ObjectQuery<T> (extensión IQueryable<T> y la versión DbQuery<T> ambas llegan internamente a esta implementación). El T define la forma de la consulta y la raíz para Include. Include se usa solo si la forma resultante de la consulta coincide con la raíz utilizada en la llamada Include. Entonces si agrega Include para llamar al IQueryable<T> y su consulta devuelve IQueryable<T> se aplica su Include pero si su consulta devuelve por ejemplo IQueryable de tipo anónimo, usted cambió la forma de la consulta y no se aplica Include.

hace que Count() se vea afectado por Include? Si es así que supongo que debería hacer conde después Incluir

Include no se utiliza si se ejecuta Count en la consulta. Count ejecuta la consulta y no devuelve el conjunto de registros de datos: cambia la forma y no hay nada que incluir.

debe Incluir ser antes o después del filtrado (¿Dónde)?

No debería importar. Incluir crea join y espero que tanto EF (al crear la consulta) como el motor de consulta en la base de datos (al ejecutar la consulta) utilicen el filtrado antes de aplicar join.

¿Realmente importa porque EF es lo suficientemente "inteligente" como para descubrirlo todo?

Solo importa si cambia la forma de la consulta: utiliza proyección o unión personalizada. En tal caso, Include de forma anterior se perderá (no se utilizará en absoluto).

+0

Solo una nota/pregunta, ¿No utilizas también incluir cuando estás ansioso por cargar? – Zapnologica

Cuestiones relacionadas