Cosa fa Include () in LINQ?


93

Ho provato a fare molte ricerche ma sono più un tipo di db, quindi anche la spiegazione nell'MSDN non ha alcun senso per me. Qualcuno può spiegare e fornire alcuni esempi su quale Include()affermazione fa nel termine della SQLquery?


Molto semplice, conosco solo semplici Seleziona, Dove, Ordina per, alcuni operatori aggregati. Non ho provato JOIN in LINQ, né Include. Il mio obiettivo finale era riscrivere queste query LINQ in SQL
CJ

Risposte:


165

Supponiamo, ad esempio, che tu voglia ottenere un elenco di tutti i tuoi clienti:

var customers = context.Customers.ToList();

E supponiamo che ogni Customeroggetto abbia un riferimento al suo insieme di Orders, e che ognuno Orderabbia riferimenti a LineItemscui può anche fare riferimento a Product.

Come puoi vedere, la selezione di un oggetto di primo livello con molte entità correlate potrebbe risultare in una query che deve estrarre dati da molte origini. Come misura delle prestazioni, Include()consente di indicare quali entità correlate devono essere lette dal database come parte della stessa query.

Utilizzando lo stesso esempio, questo potrebbe portare a tutte le intestazioni dell'ordine correlate, ma nessuno degli altri record:

var customersWithOrderDetail = context.Customers.Include("Orders").ToList();

Come punto finale da quando hai chiesto SQL, la prima istruzione senza Include()potrebbe generare una semplice dichiarazione:

SELECT * FROM Customers;

La dichiarazione finale che chiama Include("Orders")può assomigliare a questa:

SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;

1
Grazie. Utilizzando il tuo esempio, posso dire se voglio includere anche LineItemse Products, la query LINQ dovrebbe essere simile a questa var customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();:?
CJ

2
Sì, è possibile concatenare più chiamate a Include()per acquisire oggetti lungo diversi "percorsi". Se vuoi oggetti nello stesso percorso devi solo fare una chiamata che specifica l'intero percorso. Poiché LineItemse Productsnon condividete alcun componente del percorso, sono necessarie chiamate separate.
Yuck

È obbligatorio utilizzare Includi? Sono abbastanza sicuro di aver lavorato su soluzioni in cui avrei potuto ottenere oggetti correlati senza usarli.
Jepzen

@ Jepzen Dipende se stai utilizzando entità caricate in modo pigro o meno.
Yuck

@ Yuck, credo che funzioni quando si utilizza il caricamento lento, in caso di caricamento desideroso, non è necessario utilizzare l'istruzione "include", ma questo sicuramente si tradurrà in problemi di prestazioni. Per favore correggimi su questo.
sam

27

Volevo solo aggiungere che "Includi" fa parte del caricamento desideroso. È descritto nel tutorial di Entity Framework 6 di Microsoft. Ecco il link: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the -entity-framework-in-un'applicazione-asp-net-mvc


Estratto dalla pagina collegata:

Di seguito sono disponibili diversi modi in cui Entity Framework può caricare i dati correlati nelle proprietà di navigazione di un'entità:

Caricamento lento. Quando l'entità viene letta per la prima volta, i dati correlati non vengono recuperati. Tuttavia, la prima volta che si tenta di accedere a una proprietà di navigazione, i dati richiesti per tale proprietà di navigazione vengono recuperati automaticamente. Ciò si traduce in più query inviate al database: una per l'entità stessa e una ogni volta che devono essere recuperati i dati correlati per l'entità. La classe DbContext abilita il caricamento lento per impostazione predefinita.

Caricamento desideroso. Quando l'entità viene letta, i dati correlati vengono recuperati insieme ad essa. Ciò si traduce in genere in una singola query di join che recupera tutti i dati necessari. Si specifica il caricamento desideroso utilizzando il Includemetodo.

Caricamento esplicito. È simile al caricamento lento, tranne per il fatto che si recuperano esplicitamente i dati correlati nel codice; non avviene automaticamente quando accedi a una proprietà di navigazione. I dati correlati vengono caricati manualmente ottenendo la voce del gestore dello stato dell'oggetto per un'entità e chiamando il metodo Collection.Load per le raccolte o il metodo Reference.Load per le proprietà che contengono una singola entità. (Nell'esempio seguente, se si desidera caricare la proprietà di navigazione dell'amministratore, è necessario sostituirla Collection(x => x.Courses)con Reference(x => x.Administrator).) In genere si utilizza il caricamento esplicito solo quando è stato disattivato il caricamento lento.

Poiché non recuperano immediatamente i valori delle proprietà, il caricamento lento e il caricamento esplicito sono noti anche come caricamento differito.


3
Benvenuto in SO =) Solo un suggerimento ma quando rispondi a qualcosa del genere, se puoi, includi uno snippet di codice. Sfortunatamente, i collegamenti possono essere interrotti.
The_Cthulhu_Kid

2

Immaginalo come l'applicazione del caricamento desideroso in uno scenario in cui i tuoi sotto-articoli sarebbero altrimenti a caricamento lento.

L'EF di query che sta inviando al database produrrà inizialmente un risultato maggiore, ma all'accesso non verranno eseguite query di follow-up quando si accede agli elementi inclusi.

D'altra parte, senza di esso, EF eseguirà query separate in un secondo momento, quando si accede per la prima volta agli elementi secondari.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.