Esecuzione remota o locale
È possibile scegliere di eseguire le query in modalità remota, dove il motore di database esegue la query sul database, oppure localmente, dove LINQ to SQL esegue la query sulla cache locale.
Esecuzione remota
Si consideri la query seguente:
Northwnd db = new Northwnd(@"northwnd.mdf");
Customer c = db.Customers.Single(x => x.CustomerID == "19283");
foreach (Order ord in
c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
// Do something.
}
Dim db As New Northwnd("c:\northwnd.mdf")
Dim c As Customer = _
(From cust In db.Customers _
Where cust.CustomerID = 19283).First()
Dim orders = From ord In c.Orders _
Where ord.ShippedDate.Value.Year = 1998
For Each nextOrder In orders
' Do something.
Next
Se nel database sono presenti migliaia di righe di ordini, non è opportuno recuperarli tutti per elaborare un piccolo subset. In LINQ to SQL la classe EntitySet<TEntity> implementa l'interfaccia IQueryable. Questo approccio assicura che tali query possano essere eseguite in modalità remota. Questa tecnica offre due vantaggi principali:
I dati non necessari non vengono recuperati.
Una query eseguita dal motore di database è spesso più efficiente grazie agli indici del database.
Esecuzione locale
In altre situazioni può essere necessario disporre del set completo di entità correlate nella cache locale. A questo scopo EntitySet<TEntity> fornisce il metodo Load per caricare in modo esplicito tutti i membri di EntitySet<TEntity>.
Se EntitySet<TEntity> è già caricato, le query successive vengono eseguite localmente. Questo approccio risulta utile in due modi:
Se il set completo deve essere usato localmente o più volte, è possibile evitare l'esecuzione di query remote e le latenze che ne derivano.
L'entità può essere serializzata come un'entità completa.
Il frammento di codice seguente illustra come è possibile ottenere l'esecuzione locale:
Northwnd db = new Northwnd(@"northwnd.mdf");
Customer c = db.Customers.Single(x => x.CustomerID == "19283");
c.Orders.Load();
foreach (Order ord in
c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
// Do something.
}
}
Dim db As New Northwnd("c:\northwnd.mdf")
Dim c As Customer = _
(From cust In db.Customers _
Where cust.CustomerID = 19283).First
c.Orders.Load()
Dim orders = From ord In c.Orders _
Where ord.ShippedDate.Value.Year = 1998
For Each nextOrder In orders
' Do something.
Next
Confronto
Queste due funzionalità consentono di ottenere una potente combinazione di opzioni: l'esecuzione remota per le raccolte di grandi dimensioni e l'esecuzione locale per le piccole raccolte o dove è necessario disporre della raccolta completa. L'esecuzione remota viene implementata tramite IQueryable, mentre l'esecuzione locale viene implementata su una raccolta IEnumerable<T> in memoria. Per forzare l'esecuzione locale ( ovvero IEnumerable<T>), vedere Convertire un tipo in un IEnumerable generico.
Query su set non ordinati
Notare l'importante differenza tra una raccolta locale che implementa List<T> e una raccolta che fornisce query remote eseguite su set non ordinati in un database relazionale. I metodi List<T>, ad esempio quelli che usano valori di indice, richiedono la semantica di elenco che in genere non può essere ottenuta tramite una query remota su un set non ordinato. Per questo motivo, tali metodi caricano in modo implicito EntitySet<TEntity> per consentire l'esecuzione locale.