Caricamento di oggetti correlati (Entity Framework)
In questo argomento vengono descritti i modelli che è possibile utilizzare per caricare entità correlate. I tipi di entità possono definire le proprietà di navigazione che rappresentano le associazioni nel modello di dati. È possibile utilizzare queste proprietà per caricare entità correlate all'entità restituita dall'associazione definita. Quando vengono generate entità basate sul modello di dati, vengono generate proprietà di navigazione per entrambe le entità finali di un'associazione. Queste proprietà di navigazione restituiscono un riferimento sul lato "uno" di una relazione uno-a-uno o molti-a-uno o una raccolta sul lato "molti" di una relazione uno-a-molti o molti-a-molti. Per ulteriori informazioni, vedere Proprietà di navigazione e Definizione e gestione delle relazioni (Entity Framework).
Nei modelli seguenti vengono descritte la modalità di caricamento delle entità correlate:
Modello di caricamento | Descrizione |
---|---|
Specificato nella query |
È possibile creare una query Entity SQL o LINQ to Entities che navighi in modo esplicito tra le relazioni utilizzando le proprietà di navigazione. Quando si esegue una query di questo tipo, vengono restituite le entità correlate incluse come proprietà di navigazione nella proiezione più esterna della query. Per ulteriori informazioni, vedere Procedura: spostarsi nelle relazioni utilizzando le proprietà di navigazione (Entity Framework). |
Caricamento esplicito |
Per caricare in modo esplicito le entità in ObjectContext sono necessari più round trip al database e potrebbe essere necessaria la funzionalità MARS (Multiple Active Result Set), ma la quantità di dati restituiti è limitata esclusivamente alle entità caricate. Utilizzare il metodo Load su un oggetto EntityCollection o EntityReference o il metodo LoadProperty sull'oggetto ObjectContext per recuperare in modo esplicito le entità correlate dall'origine dati. Ogni chiamata al metodo Load apre una connessione al database per recuperare le informazioni correlate. In questo modo si garantisce che una query non venga mai eseguita senza una richiesta esplicita dell'entità correlata. Il caricamento esplicito è il comportamento predefinito di Entity Framework .
Nota:
Prima della chiamata a Load, una quantità ridotta di informazioni sull'entità correlata è già caricata in ObjectContext.
Per ulteriori informazioni, vedere la sezione Explicitly Loading Related Objects di questo argomento. |
Caricamento lazy |
Con questo tipo di caricamento le entità correlate vengono caricate automaticamente dall'origine dati quando si accede a una proprietà di navigazione. È inoltre necessario tenere presente che ogni proprietà di navigazione a cui si accede produce come risultato l'esecuzione di una query separata sull'origine dati se l'entità non è già in ObjectContext. Per ulteriori informazioni, vedere la sezione Lazy Loading di questo argomento. |
Caricamento eager Oppure Definizione dei percorsi della query con Include |
Se si conosce la forma esatta del grafico delle entità correlate che l'applicazione richiede, è possibile utilizzare il metodo Include nell'oggetto ObjectQuery per definire un percorso della query che controlli quali entità correlate restituire come parte della query iniziale. Quando si definisce un percorso della query, è necessaria una sola richiesta nel database per restituire tutte le entità definite dal percorso in un singolo set di risultati. Tutte le entità correlate del tipo specificato nel percorso vengono caricate con ciascun oggetto restituito dalla query. Per ulteriori informazioni, vedere la sezione Defining a Query Path to Shape Query Results di questo argomento. |
Caricamento esplicito di oggetti entità correlati
Per caricare in modo esplicito entità correlate, è necessario chiamare il metodo Load sull'entità finale correlata restituita dalla proprietà di navigazione. Per una relazione uno-a-molti, chiamare il metodo Load su EntityCollection, mentre per una relazione uno-a-uno, chiamare il metodo Load su EntityReference. Se si utilizzano entità POCO, specificare il metodo LoadProperty sull'oggetto ObjectContext. Per ulteriori informazioni, vedere Caricamento di entità POCO correlate (Entity Framework). Il metodo LoadProperty può essere utilizzato anche con le entità derivate da EntityObject. Questi metodi caricano i dati degli oggetti correlati nel contesto dell'oggetto. Quando vengono restituiti risultati da una query, è possibile enumerare la raccolta di oggetti utilizzando un ciclo foreach (For Each...Next in Visual Basic) e chiamare in modo condizionale il metodo Load sulle proprietà EntityReference e EntityCollection per ogni entità inclusa nei risultati.
Nota: |
---|
Quando si chiama il metodo Load durante un'enumerazione foreach (C#) o For Each (Visual Basic), Entity Framework tenta di aprire un nuovo lettore dati.Questa operazione non verrà eseguita correttamente a meno che non sia stata abilitata la funzionalità MARS (Multiple Active Result Set) specificando multipleactiveresultsets=true nella stringa di connessione.Per ulteriori informazioni, vedere Using Multiple Active Result Sets (MARS) in MSDN.È anche possibile caricare il risultato della query in una raccolta List. In questo caso il lettore dati viene chiuso ed è possibile enumerare la raccolta per caricare le entità di riferimento. |
Per ulteriori informazioni, vedere Procedura: caricare in modo esplicito oggetti correlati (Entity Framework).
Definizione di un percorso della query per determinare la struttura dei risultati di query
Per specificare il percorso della query, passare una rappresentazione di stringa dell'oggetto grafico al metodo Include su ObjectQuery. Questo percorso specifica quali entità correlate restituire quando viene eseguita una query di oggetto. Un percorso della query definito in una query per gli oggetti Contact garantisce, ad esempio, che vengano restituiti tutti gli oggetti SalesOrderHeader e SalesOrderDetail correlati. Questo comportamento viene illustrato nella query seguente:
' Define a LINQ query with a path that returns
' orders and items for a contact.
Dim contacts = (From contact In context.Contacts.Include("SalesOrderHeaders.SalesOrderDetails") _
Select contact).FirstOrDefault()
// Define a LINQ query with a path that returns
// orders and items for a contact.
var contacts = (from contact in context.Contacts
.Include("SalesOrderHeaders.SalesOrderDetails")
select contact).FirstOrDefault();
Le considerazioni seguenti riguardano la definizione dei percorsi della query:
I percorsi della query possono essere utilizzati con i metodi del generatore di query e con le query LINQ.
Quando si chiama Include, il percorso della query è valido solo nell'istanza restituita di ObjectQuery. Le altre istanze di ObjectQuery e il contesto dell'oggetto stesso non sono interessati.
Poiché Include restituisce l'oggetto query, è possibile chiamare questo metodo più volte su un oggetto ObjectQuery per includere entità di più relazioni, come nell'esempio seguente:
' Create a SalesOrderHeader query with two query paths, ' one that returns order items and a second that returns the ' billing and shipping addresses for each order. Dim query As ObjectQuery(Of SalesOrderHeader) = context.SalesOrderHeaders.Include("SalesOrderDetails").Include("Address")
// Create a SalesOrderHeader query with two query paths, // one that returns order items and a second that returns the // billing and shipping addresses for each order. ObjectQuery<SalesOrderHeader> query = context.SalesOrderHeaders.Include("SalesOrderDetails").Include("Address");
L'utilizzo di percorsi della query può comportare l'esecuzione di comandi complessi nell'origine dati, derivanti da query di oggetto apparentemente semplici. Questo comportamento si verifica perché sono necessari uno o più join per restituire oggetti correlati in una singola query, il che comporta la presenza di dati ridondanti per ogni entità correlata restituita dall'origine dati. Questa complessità è maggiore nelle query su un modello complesso, ad esempio un'entità con ereditarietà o un percorso che include relazioni molti-a-molti. Utilizzare il metodo ToTraceString per visualizzare il comando che verrà generato da un oggetto ObjectQuery. Quando un percorso della query include troppi oggetti correlati o gli oggetti contengono troppi dati di riga, la query potrebbe non essere completata dall'origine dati. Questo si verifica se la query richiede un'archiviazione temporanea intermedia superiore alle possibilità dell'origine dati. In questo caso, è possibile ridurre la complessità della query sull'origine dati caricando in modo esplicito gli oggetti correlati oppure abilitando il caricamento posticipato. Se dopo avere ottimizzato una query complessa si ottengono ancora timeout frequenti, aumentare il valore di timeout impostando la proprietà CommandTimeout.
Per ulteriori informazioni, vedere Procedura: utilizzare percorsi di query per influenzare i risultati (Entity Framework).
Caricamento lazy di oggetti entità
Entity Framework supporta il caricamento lazy di entità correlate. Durante il runtime di Entity Framework , il valore predefinito della proprietà LazyLoadingEnabled in un'istanza di un oggetto ObjectContext è false. Se, tuttavia, si utilizzano gli strumenti di Entity Framework per creare un nuovo modello e le corrispondenti classi generate, LazyLoadingEnabled viene impostato su true nel costruttore del contesto dell'oggetto. Con la funzione di caricamento lazy abilitata, le entità correlate non vengono caricate dall'origine dati fino a quando la funzione di accesso get di una proprietà di navigazione non accede a tali oggetti a livello di codice. Per disabilitare il caricamento lazy, impostare la proprietà LazyLoadingEnabled su false nell'istanza di ObjectContextOptions restituita dalla proprietà System.Data.Objects.ObjectContext.ContextOptions.
Il caricamento lazy può essere utilizzato insieme al caricamento eager. In questo modo, è possibile definire un grafico di dati di base tramite i percorsi della query, nonché caricare entità correlate aggiuntive non incluse nei percorsi della query originali in base alle necessità. Per ulteriori informazioni, vedere Procedura: utilizzare il caricamento lazy per caricare oggetti correlati (Entity Framework).
Quando si utilizza il caricamento lazy è utile tenere presenti le seguenti considerazioni:
Il caricamento lazy è supportato per le proprietà di navigazione che restituiscono sia un'entità singola, ad esempio EntityReference, che una raccolta di entità, ad esempio EntityCollection.
Se il caricamento lazy è abilitato ed è stata già caricata un'entità correlata, questa non verrà ricaricata.
Il caricamento lazy è supportato per le entità che si trovano in uno stato Detached. In questo caso, gli oggetti correlati vengono restituiti anche in uno stato Detached.
Il comportamento del caricamento lazy è determinato dall'istanza ObjectContext utilizzata per recuperare l'oggetto dall'origine dati (anche se l'entità è stata caricata con NoTrackingMergeOption) o alla quale l'oggetto è stato aggiunto o allegato. Per questo motivo, non è possibile modificare il comportamento del caricamento lazy una volta che il contesto è stato eliminato e qualsiasi ulteriore operazione di caricamento lazy non riuscirà.
Per la serializzazione delle entità può essere utile disabilitare il caricamento lazy. In caso contrario, verrà attivato il caricamento lazy e l'entità serializzata potrebbe includere più dati del previsto.
Quando si utilizza il caricamento lazy con entità POCO, esistono ulteriori considerazioni da tenere presente. Per ulteriori informazioni, vedere Caricamento di entità POCO correlate (Entity Framework).
Esecuzione di una query sugli oggetti entità correlati
La chiamata al metodo CreateSourceQuery su un oggetto EntityCollection consente di eseguire una query su oggetti correlati senza dover prima caricare oggetti nella raccolta. CreateSourceQuery restituisce un ObjectQuery che, in caso di esecuzione, restituisce lo stesso set di oggetti di quando viene chiamato il metodo Load. I metodi del generatore di query possono essere applicati a questa query di oggetto per filtrare ulteriormente gli oggetti caricati nella raccolta. Per ulteriori informazioni, vedere Procedura: eseguire una query sugli oggetti correlati in un oggetto EntityCollection (Entity Framework).
Un oggetto ObjectQuery restituisce i dati di entità come entità. Quando nella proiezione della query più esterna viene inclusa una proprietà di navigazione, la query restituisce tuttavia anche le entità correlate a cui ha avuto accesso tramite la navigazione. Per ulteriori informazioni, vedere Procedura: spostarsi nelle relazioni utilizzando le proprietà di navigazione (Entity Framework).
Considerazioni sulle prestazioni
Nella scelta di un modello per il caricamento di entità correlate occorre valutare il comportamento di ogni approccio considerando il numero e la durata delle connessioni effettuate all'origine dati rispetto alla quantità di dati restituita da una singola query e alla complessità dell'utilizzo di una sola query. Il caricamento eager restituisce in un'unica query tutte le entità correlate insieme alle entità sottoposte a query. Questo significa che, mentre solo una connessione è aperta verso l'origine dati, viene restituita una maggiore quantità di dati nella query iniziale. Inoltre, i percorsi della query comportano una query più complessa a causa dei join aggiuntivi richiesti nella query eseguita sull'origine dati.
Il caricamento lazy esplicito consente di posticipare la richiesta dei dati degli oggetti correlati al momento in cui sono veramente necessari. In questo modo viene prodotta una query iniziale meno complessa che restituisce meno dati totali. Tuttavia, a ogni caricamento successivo di un oggetto correlato viene effettuata una connessione all'origine dati ed eseguita una query. Nel caso di caricamento lazy, questa connessione si verifica ogni volta che viene eseguito l'accesso a una proprietà di navigazione e l'entità correlata non è già caricata. Se si è interessati a quali entità correlate vengono restituite dalla query iniziale o alla gestione dell'intervallo di tempo richiesto per il caricamento delle entità correlate dall'origine dati, potrebbe essere utile disabilitare il caricamento lazy. Il caricamento lazy è abilitato nel costruttore del contesto dell'oggetto generato da Entity Framework .
Per ulteriori informazioni, vedere Considerazioni relative alle prestazioni (Entity Framework).
Vedere anche
Concetti
Esecuzione di query su un modello concettuale (Entity Framework)
Query di oggetto (Entity Framework)
Metodi del generatore di query (Entity Framework)