2009-07-09 21 views
47

Sto utilizzando il modello di repository per l'accesso ai dati con Entity Framework e LINQ come supporto per l'implementazione del repository non di prova. La maggior parte degli esempi che vedo restituisce AsQueryable() quando la chiamata restituisce N records invece di List < T>. Qual è il vantaggio di fare questo?Perché utilizzare AsQueryable() anziché List()?

+2

Che cos'è un archivio non di prova? –

risposta

79

AsQueryable crea solo una query, le istruzioni necessarie per ottenere un elenco. È possibile apportare ulteriori modifiche alla query in seguito, ad esempio aggiungendo nuove clausole Where che vengono inviate fino al livello del database.

AsList restituisce una lista reale con tutte le voci in memoria. Se aggiungi un nuovo clone Where, non ottieni il filtro veloce fornito dal database. Invece ottieni tutte le informazioni nella lista e poi filtra ciò che non ti serve nell'applicazione.

Quindi in pratica si tratta di aspettare fino all'ultimo momento possibile prima di impegnarsi.

+4

d'accordo, ma ricorda che oltre al "filtraggio veloce", c'è anche il colpo di inviare tutte queste informazioni attraverso la rete. – eglasius

+0

Inoltre, non è l'unico modo per farlo, dato che potresti ricevere i filtri da applicare invece di restituire qualcosa che può essere filtrato. Il primo è più facile da usare se in seguito si passa dall'utilizzo di un db a qualcos'altro, ad esempio un servizio Web o qualsiasi altra cosa. – eglasius

+10

Un altro punto: se restituisci un IQueryable devi trovare un buon modo per assicurarti che 1.) il contesto sia aperto fino a quando la query viene eseguita e 2.) che il contesto sia disposto correttamente. Restituire una lista ha il vantaggio di poter controllare la durata del contesto all'interno di un metodo. Ciò che si adatta meglio dipende dai requisiti effettivi. –

4

Il reso IQueryable<T> rinvia l'esecuzione della query finché i suoi risultati non vengono effettivamente utilizzati. Fino ad allora, è anche possibile eseguire operazioni di query sul database aggiuntive su IQueryable<T>; su un List ci si limita a operazioni in memoria generalmente meno efficienti.

+0

Penso che sia quello che Grauenwolf ha già detto: P :) – eglasius

+0

La sua risposta è stata presentata mentre scrivevo la mia. :) – dahlbyk

19

Il ripristino di IQueryable<T> ha il vantaggio che l'esecuzione è defferer fino a quando non si avvia effettivamente l'enumerazione del risultato e si può comporre la query con altre query e ottenere comunque l'esecuzione lato server.

Il problema è che non è possibile controllare la durata del contesto del database in questo metodo: è necessario un contesto aperto e assicurarsi che rimanga aperto fino all'esecuzione della query. E quindi devi assicurarti che il contesto sia smaltito. Se restituisci il risultato come List<T>, T[], o qualcosa di simile, perdi l'esecuzione deffered e l'esecuzione lato server delle query composte, ma ottieni il controllo sulla durata del contesto del database.

Ciò che si adatta meglio, ovviamente, dipende dai requisiti effettivi. È un'altra domanda senza una sola verità.

9

AsQueryable è un metodo di estensione per IEnumerable<T> che potrebbe fare due cose:

  • Se i IEnumerable<T> implementa IQueryable<T> Justs calchi, non fare nulla.
  • In caso contrario, crea un 'falso' IEnumerable<T> (EnumerableQuery<T>) che implementa tutti i metodi che compongono i lambda e chiamano a Enumerazione metodi di estensione.

Quindi, nella maggior parte dei casi utilizzando AsQueryable è inutile, a meno che u sono costretti a passare un IQueryable ad un metodo e u avere un IEnumerable, invece, si tratta di un hack.

NOTA: AsQueryable è un hack, IQueryable ovviamente non lo è!

+2

AsQueryable non è inutile, in quanto il codice utente che si è "obbligato a passare come IQueryable" è valido, consente di utilizzare ciò che IQueryable ha da offrire e che è più di IEnumerable. Non lo considererei un hack, e ha i suoi usi, si veda ad esempio qui: http://wcf.codeplex.com/wikipage?title=Getting%20started:%20Building%20a%20simple%20web%20api. Ma immagino che quello che vuoi dire è che non può essere usato per approfondire e influenzare il modo in cui vengono prodotti i dati Enumerable (ad esempio, ottimizzando una query), funzionerà solo in base a ciò che viene creato/ottenuto. –

+0

IQueryable e AsQueryable mi hanno appena salvato la vita –

Problemi correlati