Domanda

In una classe LINQ to SQL, perché sono le proprietà create dagli oggetti EntitySet di chiavi esterne, che implementano IEnumerable , dove come oggetti sul DataContext sono oggetti Table che implementano IQueryable ?

MODIFICA: Per chiarire, ecco un esempio che illustra ciò che sto cercando di capire. Questo esempio:

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

colpisce due volte il database dove:

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

esegue solo 1 query. Ecco le tracce:

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

e

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

che mostra anche che, peggio ancora, il massimo è fatto a livello di C # piuttosto che nel database.

So che la ragione per cui ciò accade è la differenza tra IQueryable se IEnumerable , quindi perché l'oggetto MatchPlayers in il primo esempio implementa l'interfaccia IQueryable per ottenere gli stessi vantaggi del secondo esempio.

È stato utile?

Soluzione

Le tabelle sono effettivamente una questione concettuale: esistono davvero sul server, quindi è necessario eseguire una query per ottenere voci. Le voci della chiave esterna sono quelle effettivamente recuperate da un'altra query, quindi a quel punto sono disponibili localmente. Questa è una descrizione abbastanza lanosa, ma si spera vada oltre il concetto generale.

Altri suggerimenti

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

Single () restituisce una corrispondenza, non IQueryable (corrispondenza).

Basta spingere Single () sull'ultimo passaggio:

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

Ciò che mostra questa query è che è giusto usare la proprietà MatchPlayers in una query. Che affronta la mia interpretazione della domanda del richiedente - " Perché non posso usare un EntitySet in una query? & Quot ;, Puoi. ??

Questo era Indirizzato sui forum MSDN . L'essenza del ragionamento è che è molto difficile tenere traccia degli oggetti aggiunti e rimossi mentre si eseguono query sul database. Invece, EntitySet è una specie di copia locale degli oggetti correlati che è possibile manipolare. Sfortunatamente, come hai notato, questo ha l'effetto collaterale di deviare le espressioni nelle chiamate LINQ to Objects invece che LINQ to SQL con le migliori prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top