Question

Dans une classe LINQ to SQL, pourquoi les propriétés créées à partir des objets EntitySet de clés étrangères, qui implémentent IEnumerable , où sont les objets du DataContext sont des objets Table qui implémentent IQueryable ?

MODIFIER: Pour clarifier, voici un exemple illustrant ce que j'essaie de comprendre. Cet exemple:

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

frappe deux fois dans la base de données là où:

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

n'exécute qu'une seule 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 également que, pire encore, le max est effectué au niveau C # plutôt que dans la base de données.

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

Était-ce utile?

La solution

Les tables sont en réalité une affaire conceptuelle - elles existent vraiment sur le serveur, vous devez donc interroger pour obtenir des entrées. Les entrées de clé étrangère sont celles qui sont réellement extraites par une autre requête, elles sont donc localement disponibles. C'est une description assez laineuse, mais j'espère que cela dépasse le concept général.

Autres conseils

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

Single () renvoie une correspondance et non un IQueryable (correspondance).

Appuyez simplement sur Single () jusqu'à la dernière étape:

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

Ce que cette requête montre, c'est qu'il est correct d'utiliser la propriété MatchPlayers dans une requête. Cela répond à mon interprétation de la question de l’interrogateur: "Pourquoi ne puis-je pas utiliser un EntitySet dans une requête?", Vous pouvez.

Il s'agissait de Adressé sur les forums MSDN . Le raisonnement est qu'il est très difficile de suivre les objets ajoutés et supprimés tout en effectuant des requêtes sur la base de données. EntitySet est plutôt une copie locale des objets liés que vous pouvez manipuler. Malheureusement, comme vous l'avez remarqué, cela a pour effet secondaire de déplacer les expressions dans LINQ vers des appels d'objets au lieu des applications LINQ to SQL les plus performantes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top