2011-10-20 17 views
7

Sto accedendo a un'origine dati remota e ho riscontrato che un'unione di gruppo comporta la trasformazione di una query IQueryable in una variabile IEnumerable,L'unione di un gruppo fa diventare IQueryable in IEnumerable, perché?

: influirà sulle prestazioni? Voglio scaricare il maggior numero di query al database come possibile, e non esegue nulla nella 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 linea: .GroupJoin (_abilities, x => x.eProfile.ID , y => y.ID, (x, y) => new QuoteDTO

  1. _abilities è un IQueryable, ottengo la capacità di un utente, un insieme di oggetti
  2. la seconda parte (x , y) - qui y viene trasformato in un oggetto IEnumerable ...

var cLists = List<int>(); // questa collezione è popolato dal codice del client, permette di dire che // contiene 1,3,55 per amor di argomenti ...

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

NOTA: il motivo per cui ho uso var è così che io possa trasformare in un oggetto di mio gradimento, stavo usando un sacco di tipi anonimi, prima sono stati inseriti gli oggetti DTO ...

+0

Quale bit viene "trasformato in un oggetto IEnumerable"? E quali sono le abilità? –

+0

È una query secondaria, ho aggiornato il codice sopra ... – Haroon

+0

È '_abilities' un' IQueryable'? Qual è il tipo di dati di tutte le tue variabili? Per favore non usare 'var', non possiamo dedurre i tipi di variabile e il compilatore. – Greg

risposta

1

La definizione di IQueryable:

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

... e ObjectQuery:

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

La maggior parte (? Tutti) LINQ espressioni restituire un cast oggetto come IEnumerable. Ma il tipo dell'oggetto rimane il tipo da cui è iniziato.

No, il database non viene colpito quando una query LINQ-to-Entities viene eseguita come IEnumerable, quindi le prestazioni non vengono compromesse. Se lo desideri, puoi eseguire l'upcast su IQueryable o su ObjectQuery.

Modifica: per chiarimenti, chiamare ToArray() su un'istanza di ObjectQuery, IQueryable o IEnumerable colpisce il database e recupera un set di risultati.

Modifica: la creazione di un nuovo oggetto all'interno di una query (cioè nuovo QuoteDTO) colpirà il database, poiché non è possibile memorizzare il nuovo oggetto in una query SQL. Scusate, mi mancava un po 'prima.

+0

Sembra che il mio codice colpisca effettivamente il db per le sue sottoquery, questo è il mio vero problema, ho pensato di porre la domanda sopra per aiutarmi a risolvere anche questo – Haroon

+0

You ' Hai ragione. Ho modificato la mia risposta. La creazione di un "nuovo" oggetto all'interno di una query colpirà il database e restituirà il set di risultati. – ken

+0

Quindi dovrei creare un oggetto anonimo per ogni query, in questo modo non entrerò nel database? – Haroon

Problemi correlati