2008-10-14 3 views
9

Dans un LINQ à la classe SQL, pourquoi sont les propriétés qui sont créés à partir des clés étrangères EntitySet objets qui mettent en œuvre IEnumerable, où les objets du DataContext sont Table objets qui mettent en œuvre IQueryable?EntitySet vs tableau les performances des requêtes dans LINQ2SQL

EDIT: Pour clarifier, voici un exemple qui illustre ce que j'essaie de comprendre. Cet exemple:

ctx.Matches.Where(x => x.MatchID == 1).Single() 
      .MatchPlayers.Max(x => x.Score); 

frappe deux fois la base de données où que:

ctx.MatchPlayers.Where(x => x.MatchID == 1) 
       .Max(x => x.Score); 

ne fonctionne que 1 requête. Voici les traces:

exec sp_executesql N'SELECT [t0].[MatchID], [t0].[Date] 
FROM [dbo].[Matches] AS [t0] 
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1 
go 
exec sp_executesql N'SELECT [t0].[MatchID], [t0].[PlayerID], [t0].[Score] 
FROM [dbo].[MatchPlayers] AS [t0] 
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1 
go 

et

exec sp_executesql N'SELECT MAX([t0].[Score]) AS [value] 
FROM [dbo].[MatchPlayers] AS [t0] 
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1 
go 

qui montre aussi que, pire encore, le maximum est fait au niveau C# plutôt que dans la base de données.

Je sais que la raison pour laquelle cela se produit est la différence entre IQueryable s et IEnumerable s, alors pourquoi ne pas l'objet MatchPlayers dans le premier exemple implémenter l'interface IQueryable pour obtenir les mêmes avantages que le dernier exemple.

Répondre

1

Les tables sont effectivement un concept - elles existent réellement sur le serveur, vous devez donc faire une requête pour obtenir des entrées. Les entrées de clé étrangère sont celles qui sont réellement récupérées par une autre requête, elles sont donc disponibles localement à ce moment-là. C'est une description assez laineuse, mais j'espère que cela dépasse le concept général. Single() renvoie une correspondance et non une erreur IQueryable (correspondance).

3
ctx.Matches.Where(x => x.MatchID == 1).Single() 

Single() renvoie une correspondance.

Il suffit de pousser unique() au large à la dernière étape:

ctx.Matches 
    .Where(m => m.MatchID == 1) 
    .Select(m => m.MatchPlayers.Max(mp => mp.Score)) 
    .Single(); 

Qu'est-ce que cette requête montre est, qu'il est autorisé à utiliser la propriété MatchPlayers dans une requête. Ce qui répond à mon interprétation de la question du demandeur - "Pourquoi ne puis-je pas utiliser un EntitySet dans une requête?", Vous pouvez.

0

C'était addressed on the MSDN forums. L'essentiel du raisonnement est qu'il est très difficile de suivre les objets ajoutés et supprimés tout en faisant des requêtes sur la base de données. Au lieu de cela, EntitySet est quelque chose d'une copie locale des objets liés que vous pouvez manipuler. Malheureusement, comme vous l'avez remarqué, cela a pour effet secondaire de transférer des expressions dans les appels LINQ to Objects à la place de LINQ to SQL plus performant.

Questions connexes