2011-10-20 10 views
7

Estoy accediendo a una fuente de datos remota y encontré que una unión de grupo provoca que una consulta IQueryable se transforme en una pregunta IEnumerable,La unión de grupo hace que IQueryable se convierta en IEnumerable, ¿por qué?

: ¿afectará esto al rendimiento? Quiero sacar datos tanto de la consulta a la base de datos como sea posible, y no ejecutar nada en la memoria ...

var allusers = repo.All<User>().Where(x => x.IsActive); 
var _eprofile = repo.All<Profile>() 
    .Where(x => x.IsProfileActive) 
    .Join(allusers, x => x.UserID, y => y.UserID, (x, y) => new 
    { 
     eProfile = x, 
     profile = y 
    }) 
    .GroupJoin(_abilities, x => x.eProfile.ID, y => y.ID, (x, y) => new QuoteDTO 
    { 
     UserID = x.profile.Login, 
     Email = x.profile.Email, 
     Tel = x.profile.Tel, 
     Mobile = x.eProfile.Mobile, 
     CompanyID = x.profile.CompanyID, 
     Ability = y.Select(c => new AbilityDTO 
    { 
     Name= c.Name 
    }) 

    }); 

La línea: .GroupJoin (_abilities, x => x.eProfile.ID , y => y.ID, (x, y) => nuevo QuoteDTO

  1. _abilities es un IQueryable, consigo la capacidad de un usuario, una colección de objetos
  2. la segunda parte (x , y) - aquí y se transforma en un IEnumerable ...

var cLists = List<int>(); // está poblada esta colección desde el código de cliente, digamos que // contiene 1,3,55 para el bien de los argumentos ...

var _abilities= repo.All<UserAbility>() 
     .Where(x => x.Status == Status.Active.ToString()) 
     .Where(x => cLists.Contains(x.CompetencyID)); 

NOTA: la razón por la que var uso es para que pueda transformarse en un objeto de mi gusto, yo estaba usando una gran cantidad de tipos anónimos antes de que se insertan los objetos DTO ...

+0

¿Qué bit está siendo "transformado en un Enumerable"? ¿Y qué es _capacidades? –

+0

Es una sub consulta, he actualizado el código anterior ... – Haroon

+0

¿'_abilities' an' IQueryable'? ¿Cuál es el tipo de datos de todas sus variables? Por favor, no use 'var', no podemos inferir los tipos de variables tan bien como el compilador. – Greg

Respuesta

1

La definición de IQueryable:

public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable 

... y ObjectQuery:

ObjectQuery<T> : ObjectQuery, IOrderedQueryable<T>, IQueryable<T>, IEnumerable<T>, IOrderedQueryable, IQueryable, IEnumerable, IListSource 

La mayoría (? Todas) las expresiones LINQ devuelve un elenco objeto como IEnumerable. Pero el tipo de objeto sigue siendo el tipo en el que comenzó.

No, la base de datos no se ve afectada cuando una consulta LINQ-to-Entities se convierte en IEnumerable, por lo que el rendimiento no se ve comprometido. Si lo desea, puede subir a IQueryable u ObjectQuery.

Editar: Para aclarar, llamar a ToArray() en una instancia de ObjectQuery, IQueryable o IEnumerable golpea la base de datos y recupera un conjunto de resultados.

Editar: Crear un nuevo objeto dentro de una consulta (es decir, un nuevo QuoteDTO) golpeará la base de datos, porque no hay forma de almacenar el nuevo objeto en una consulta SQL. Lo siento, me perdí ese poco antes.

+0

Parece como si mi código realmente golpeara el DB por sus sub consultas, ese es mi problema real, pensé que hacer la pregunta anterior también me ayudaría a resolverlo – Haroon

+0

You ' estas en lo correcto. Edité mi respuesta. Crear un objeto "nuevo" dentro de una consulta golpeará la base de datos y devolverá el conjunto de resultados. – ken

+0

Entonces, ¿debería hacer un objeto anónimo para cada consulta, de esa manera no golpearé la base de datos? – Haroon

Cuestiones relacionadas