Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le query su Entity Framework sono rappresentate da query ad albero dei comandi, eseguite sul contesto dell'oggetto. LINQ to Entities consente di convertire query LINQ (Language-Integrated Query) in query ad albero dei comandi, eseguire le query su Entity Framework e restituire oggetti che possono essere utilizzati sia da Entity Framework sia da LINQ. Di seguito viene descritto il processo di creazione ed esecuzione di una query LINQ to Entities:
Costruire un'istanza di ObjectQuery da ObjectContext.
Comporre una query LINQ to Entities in C# o Visual Basic utilizzando l'istanza di ObjectQuery.
Convertire gli operatori e le espressioni di query standard LINQ in alberi dei comandi.
Eseguire la query, nella rappresentazione ad albero dei comandi, sull'origine dati. Tutte le eccezioni generate nell'origine dati durante l'esecuzione vengono passate direttamente al client.
Restituire i risultati della query al client.
Costruzione di un'istanza di ObjectQuery
La classe generica ObjectQuery rappresenta una query che restituisce un insieme di zero o più entità tipizzate. Una query di oggetto viene in genere costruita da un contesto dell'oggetto esistente anziché manualmente e appartiene sempre a tale contesto dell'oggetto. Il contesto fornisce le informazioni relative a connessione e metadati necessarie per comporre ed eseguire la query. La classe generica ObjectQuery implementa l'interfaccia generica IQueryable, i cui metodi del generatore consentono la compilazione incrementale delle query LINQ.
Composizione della query
Le istanze della classe generica ObjectQuery, che implementa l'interfaccia generica IQueryable, fungono da origine dati per le query LINQ to Entities. In una query è necessario specificare con esattezza le informazioni che si desidera recuperare dall'origine dati. Una query può inoltre specificare il modo in cui ordinare, raggruppare e formattare le informazioni prima che vengano restituite. In LINQ una query viene archiviata in una variabile. Tale variabile di query non esegue azioni né restituisce dati, ma viene utilizzata solo per archiviare le informazioni sulla query. Dopo avere creato una query, è necessario eseguirla per recuperare tutti i dati.
Le query LINQ to Entities possono essere composte in due sintassi diverse, ovvero la sintassi delle espressioni di query e la sintassi delle query basate su metodo. La sintassi delle espressioni di query e la sintassi delle query basate su metodo rappresentano una novità in C# 3.0 e Visual Basic 9.0.
Per ulteriori informazioni, vedere Query in LINQ to Entities.
Nell'esempio di sintassi delle espressioni di query seguente viene costruita un'istanza di ObjectQuery dal contesto dell'oggetto AdventureWorks e viene utilizzato Select per restituire tutte le righe di Product.
Using AWEntities As New AdventureWorksEntities
Dim products As ObjectQuery(Of Product) = AWEntities.Product
Dim productNames = _
From p In products _
Select p
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
ObjectQuery<Product> products = AWEntities.Product;
IQueryable<Product> productNames =
from p in products
select p;
}
Nell'esempio di sintassi delle query basate su metodo seguente viene costruita un'istanza di ObjectQuery dal contesto dell'oggetto AdventureWorks e viene utilizzato Select per restituire tutte le righe di Product.
Using AWEntities As New AdventureWorksEntities
Dim productNames = AWEntities.Product.Select(Function(p) p.Name)
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
ObjectQuery<Product> products = AWEntities.Product;
IQueryable<Product> productNames = products.Select(p => p);
}
Conversione della query
Per eseguire una query LINQ to Entities su Entity Framework, è necessario convertire la query LINQ in una rappresentazione ad albero dei comandi che possa essere eseguita su Entity Framework.
Le query LINQ to Entities includono operatori di query standard LINQ, ad esempio Select, Where e GroupBy, ed espressioni (x > 10, Contact.LastName e così via). Gli operatori LINQ non sono definiti da una classe, ma sono piuttosto metodi in una classe. In LINQ le espressioni possono contenere tutto ciò che è consentito dai tipi all'interno dello spazio dei nomi System.Linq.Expressions e, per estensione, tutto ciò che può essere rappresentato in una funzione lambda. Si tratta di un superset delle espressioni consentite da Entity Framework, per definizione limitate alle operazioni consentite sul database, e supportate da ObjectQuery.
In Entity Framework sia gli operatori sia le espressioni sono rappresentati da una singola gerarchia dei tipi e vengono quindi inclusi in un albero dei comandi. L'albero dei comandi viene utilizzato da Entity Framework per eseguire la query. Se la query LINQ non può essere espressa come albero dei comandi, viene generata un'eccezione durante la conversione della query. La conversione di query LINQ to Entities comporta due conversioni secondarie: la conversione degli operatori di query standard e la conversione delle espressioni.
Per un certo numero di operatori di query standard LINQ non è disponibile una conversione valida in LINQ to Entities. Qualsiasi tentativo di utilizzare tali operatori restituirà un'eccezione in fase di conversione della query. Per un elenco degli operatori LINQ to Entities supportati, vedere Metodi supportati e non supportati (LINQ to Entities).
Per ulteriori informazioni sull'utilizzo di operatori di query standard in LINQ to Entities, vedere Operatori di query standard nelle query LINQ to Entities.
Poiché in generale le espressioni in LINQ to Entities vengono valutate nel server, non è previsto che il comportamento dell'espressione sia conforme alla semantica CLR. Per ulteriori informazioni, vedere Espressioni nelle query LINQ to Entities.
Esecuzione della query
Al termine della creazione della query LINQ da parte dell'utente, la query viene convertita in una rappresentazione compatibile con Entity Framework, sotto forma di alberi dei comandi, e viene quindi eseguita sull'origine dati. In fase di esecuzione della query tutte le espressioni di query, o i componenti della query, vengono valutate nel client o nel server, incluse le espressioni utilizzate nella materializzazione dei risultati o nelle proiezioni di entità.
Un'espressione di query può essere eseguita in momenti diversi. Le query LINQ vengono eseguite a ogni iterazione, e non durante la creazione, della variabile di query. Questo comportamento è noto come esecuzione posticipata. È inoltre possibile forzare l'esecuzione immediata della query, utile per la memorizzazione nella cache dei risultati della query. Nell'esempio seguente viene utilizzato Select per restituire tutte le righe di Product e visualizzare i nomi di prodotto. L'iterazione della variabile di query nel ciclo foreach/For Each provoca l'esecuzione della query.
Using AWEntities As New AdventureWorksEntities
Dim products As ObjectQuery(Of Product) = AWEntities.Product
Dim productNames = _
From p In products _
Select p.Name
Console.WriteLine("Product Names:")
For Each productName In productNames
Console.WriteLine(productName)
Next
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
ObjectQuery<Product> products = AWEntities.Product;
IQueryable<string> productNames =
from p in products
select p.Name;
Console.WriteLine("Product Names:");
foreach (var productName in productNames)
{
Console.WriteLine(productName);
}
}
Quando viene eseguita una query LINQ to Entities, è possibile che alcune espressioni nella query vengano eseguite nel server e che alcune parti vengano eseguite localmente nel client. La valutazione sul lato client di un'espressione viene effettuata prima dell'esecuzione della query nel server. Se un'espressione viene valutata nel client, il risultato della valutazione sostituisce l'espressione nella query e la query viene quindi eseguita nel server. Poiché le query vengono eseguite sull'origine dati, la configurazione dell'origine dati prevale sul comportamento specificato nel client. Due esempi di questo comportamento sono rappresentati dalla gestione dei valori Null e dalla precisione numerica. Tutte le eccezioni generate durante l'esecuzione della query nel server vengono passate direttamente al client. Per ulteriori informazioni, vedere Esecuzione di query.
Materializzazione
La materializzazione è il processo di restituzione dei risultati della query al client come tipi CLR. In LINQ to Entities i record di dati dei risultati della query non vengono mai restituiti, ma è sempre disponibile un tipo CLR di supporto definito dall'utente o da Entity Framework oppure generato dal compilatore (tipi anonimi). Tutta la materializzazione degli oggetti viene eseguita da Entity Framework. Qualsiasi errore correlato all'impossibilità di eseguire il mapping tra Entity Framework e CLR comporterà la generazione di eccezioni durante la materializzazione degli oggetti.
I risultati della query vengono in genere restituiti come uno degli elementi seguenti:
Insieme di zero o più oggetti entità tipizzati o proiezione di tipi complessi in EDM.
Tipi CLR supportati da EDM.
Insiemi inline.
Tipi anonimi.
Per ulteriori informazioni, vedere Risultati delle query.