EntitySet vs Tabla de rendimiento en LINQ2SQL
-
03-07-2019 - |
Pregunta
En una clase LINQ to SQL, ¿por qué son las propiedades que se crean a partir de los objetos EntitySet
de claves foráneas, que implementan IEnumerable
, donde los objetos en el DataContext
son objetos Table
que implementan IQueryable
?
EDITAR: Para aclarar, aquí hay un ejemplo que ilustra lo que estoy tratando de entender. Este ejemplo:
ctx.Matches.Where(x => x.MatchID == 1).Single()
.MatchPlayers.Max(x => x.Score);
llega a la base de datos dos veces donde:
ctx.MatchPlayers.Where(x => x.MatchID == 1)
.Max(x => x.Score);
solo ejecuta 1 consulta. Aquí están las huellas:
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
y
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
que también muestra que, lo que es peor, el máximo se realiza en el nivel de C # en lugar de en la base de datos.
Sé que la razón por la que esto sucede es la diferencia entre IQueryable
y IEnumerable
s, entonces, ¿por qué el MatchPlayers
no se opone a el primer ejemplo implementa la interfaz IQueryable
para obtener los mismos beneficios que el último ejemplo.
Solución
Las tablas son efectivamente una cuestión conceptual: realmente existen en el servidor, por lo que debe consultar para obtener entradas. Las entradas de clave externa son las que realmente obtiene otra consulta, por lo que en ese momento están disponibles localmente. Esa es una descripción bastante laxa, pero espero que supere el concepto general.
Otros consejos
ctx.Matches.Where(x => x.MatchID == 1).Single()
Single () devuelve un Match, no un IQueryable (Match).
Simplemente empuje Single () al último paso:
ctx.Matches
.Where(m => m.MatchID == 1)
.Select(m => m.MatchPlayers.Max(mp => mp.Score))
.Single();
Lo que muestra esta consulta es que está bien usar la propiedad MatchPlayers en una consulta. ¿Qué aborda mi interpretación de la pregunta del autor de la pregunta? "¿Por qué no puedo usar un EntitySet en una consulta?" "Puedes".
Esto era Abordado en los foros de MSDN . La esencia del razonamiento es que es muy difícil rastrear objetos agregados y eliminados mientras se realizan consultas en la base de datos. En cambio, el EntitySet es una especie de copia local de los objetos relacionados que puede manipular. Desafortunadamente, como notó, esto tiene el efecto secundario de transferir expresiones a las llamadas de LINQ to Objects en lugar del mejor rendimiento de LINQ to SQL.