2010-05-05 9 views
6

Dans l'environnement .NET 4 et multicœur, l'objet linq to sql datacontext utilise-t-il les nouveaux parallèles si nous utilisons DataLoadOptions.LoadWith?LinqToSql - Parallèle - DataContext et Parallèle

EDIT

Je sais LINQ to SQL ne paralléliser pas les requêtes ordinaires. Ce que je veux savoir, c'est quand nous spécifions DataLoadOption.LoadWith, utilise-t-il la parallélisation pour effectuer la correspondance entre chaque entité et ses sous-entités?

Exemple:

using(MyDataContext context = new MyDataContext()) 
{ 
    DataLaodOptions options =new DataLoadOptions(); 
    options.LoadWith<Product>(p=>p.Category); 
    return this.DataContext.Products.Where(p=>p.SomeCondition); 
} 

génère l'instruction SQL suivante:

Select Id,Name from Categories 
Select Id,Name, CategoryId from Products where p.SomeCondition 

lorsque tous les produits sont créés, aurons-nous un

categories.ToArray(); 
Parallel.Foreach(products, p => 
{ 
    p.Category == categories.FirstOrDefault(c => c.Id == p.CategoryId); 
}); 

ou

categories.ToArray(); 
foreach(Product product in products) 
{ 
    product.Category = categories.FirstOrDefault(c => c.Id == product.CategoryId); 
} 

?

+0

N'oubliez pas de signaler votre réponse préférée ;-) – Steven

+0

@Steven: J'espérais des réponses à mon edit ... – Gregoire

+0

Il n'y a pas d'optimisation parallèle quoi que ce soit à l'intérieur de L2S. Voir ma mise à jour – Steven

Répondre

10

Non, LINQ to SQL ne le fait pas. Il y a peu à paralléliser sur le côté .NET. Tout ce que fait LINQ to SQL est la traduction des arbres d'expression en requêtes SQL. SQL Server exécutera ces instructions SQL et pourra le faire en parallèle.

Ne pas oublier que si vous pouvez faire quelque chose comme ceci avec votre requête LINQ to SQL LINQ, ce n'est pas une bonne idée:

// BAD CODE!!! Don't parallelize a LINQ to SQL query 
var q = 
    from customer in db.Customers.AsParallel() 
    where customer.Id == 5 
    select customer; 

Bien que cela donne des résultats corrects, vous ne serez pas obtenir l'amélioration de la performance que vous espérez. PLINQ n'est pas capable de gérer les objets IQueryable. Par conséquent, il va simplement gérer un IQueryable en tant que IEnumerable (l'itérant ainsi). Il traitera la collection db.Customers en parallèle et utilisera plusieurs threads pour filtrer les clients. Bien que cela semble correct, cela signifie qu'il va récupérer la collection complète des clients de la base de données! Sans la construction AsParallel, LINQ to SQL serait en mesure d'optimiser cette requête en ajoutant le WHERE id = @ID au SQL. SQL Server serait capable d'utiliser des index (et éventuellement des threads multiples) pour récupérer les valeurs.

Bien qu'il y ait une marge d'optimisation dans le moteur LINQ to SQL quand il s'agit de faire correspondre des entités à ses sous-entités, il ne semble pas y avoir une telle optimisation dans le framework (ou du moins trouvez-en utilisant Reflector).

+0

Merci pour votre réponse. Je le savais pour ce cas particulier. Ce que je voudrais savoir c'est ce qui arrive quand des options de chargement de données sont spécifiées? – Gregoire

+0

Je suis désolé. Je ne suis pas sûr de ce que tu veux savoir. Pour autant que je sache, LINQ to SQL ne fera pas d'accélération interne en utilisant des constructions parallèles. Bien sûr, vous êtes libre de faire votre propre optimisation parallèle dans l'espace .NET avec PLINQ (aux objets) lorsque LINQ to SQL est chargé. – Steven