EntitySet vs Prestazioni query tabella in LINQ2SQL
-
03-07-2019 - |
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.
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.