Comparaison entre une exécution de requête locale et une exécution de requête distante (LINQ to SQL)
Vous pouvez décider d'exécuter vos requêtes à distance (autrement dit, le moteur de base de données exécute la requête sur la base de données) ou localement (LINQ to SQL exécute la requête sur un cache local).
Communication à distance
Prenons la requête suivante :
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
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.
}
Si votre base de données contient des milliers de lignes de commandes, vous ne souhaitez pas toutes les récupérer pour traiter un petit sous-ensemble. Dans LINQ to SQL, la classe EntitySet<TEntity> implémente l'interface IQueryable. Cette approche permet de s'assurer que de telles requêtes peuvent être exécutées à distance. Deux avantages majeurs découlent de cette technique :
Les données inutiles ne sont pas récupérées.
Une requête exécutée par le moteur de base de données est souvent plus efficace en raison des index de la base de données.
Exécution locale
Dans d'autres situations, vous pouvez souhaiter disposer du jeu complet d'entités connexes dans le cache local. Pour cela, EntitySet<TEntity> fournit la méthode Load pour charger explicitement tous les membres de EntitySet<TEntity>.
Si un EntitySet<TEntity> est déjà chargé, les requêtes suivantes sont exécutées localement. Cette approche est utile pour les raisons suivantes :
Si le jeu complet doit être utilisé localement ou plusieurs fois, vous pouvez éviter des requêtes distantes et des latences associées.
L'entité peut être sérialisée comme une entité complète.
Le fragment de code suivant illustre comment obtenir l'exécution locale :
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
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.
}
}
Comparaison
Ces deux fonctions fournissent une combinaison puissante d'options : communication à distance pour les grandes collections et exécution locale pour les petites collections ou lorsque la collection complète est nécessaire. Implémentez la communication à distance via IQueryable et l'exécution locale sur une collection IEnumerable<T> en mémoire. Pour forcer l'exécution locale (autrement dit, IEnumerable<T>), consultez Procédure : convertir un type en IEnumerable générique (LINQ to SQL).
Requêtes sur des jeux non ordonnés
Notez la différence importante entre une collection locale qui implémente List<T> et une collection qui fournit des requêtes distantes exécutées sur des jeux non ordonnés dans une base de données relationnelle. Les méthodes List<T> telles que celles qui utilisent des valeurs d'index requièrent des sémantiques de liste que l'on ne peut généralement pas obtenir via une requête distante sur un jeu non ordonné. Pour cette raison, de telles méthodes chargent implicitement le EntitySet<TEntity> pour autoriser l'exécution locale.