EntitySet vs desempenho Tabela consulta no LINQ2SQL
-
03-07-2019 - |
Pergunta
Em um LINQ to SQL classe, por que são as propriedades que são criados a partir das chaves estrangeiras EntitySet
objetos, que implementam IEnumerable
, onde, como os objetos na DataContext
são objetos Table
que implementam IQueryable
?
EDIT: Para esclarecer, aqui é um exemplo que ilustra o que estou tentando entender. Este exemplo:
ctx.Matches.Where(x => x.MatchID == 1).Single()
.MatchPlayers.Max(x => x.Score);
bate o banco de dados duas vezes onde, como:
ctx.MatchPlayers.Where(x => x.MatchID == 1)
.Max(x => x.Score);
funciona somente 1 consulta. Aqui estão os vestígios:
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
que também mostra que, ainda pior, o máximo é feito no nível C # e não no banco de dados.
Eu sei que a razão para isso é a diferença entre IQueryable
s e IEnumerable
s, então por que não o objeto MatchPlayers
no primeiro exemplo implementar a interface IQueryable
para obter os mesmos benefícios como o último exemplo.
Solução
As tabelas são efetivamente uma questão conceitual - eles realmente existem no servidor, então você precisa para consulta para obter entradas. As entradas de chaves estrangeiras são os únicos realmente obtida por outra consulta, então nesse ponto eles estão disponíveis localmente. Essa é uma descrição bastante confusa, mas espero que ele fica sobre o conceito geral.
Outras dicas
ctx.Matches.Where(x => x.MatchID == 1).Single()
Single () retorna um Match, não um IQueryable (Match).
Basta apertar Individual () fora para o último passo:
ctx.Matches
.Where(m => m.MatchID == 1)
.Select(m => m.MatchPlayers.Max(mp => mp.Score))
.Single();
O que isto mostra é de consulta, que é ok para usar a propriedade MatchPlayers em uma consulta. Que aborda a minha interpretação da pergunta do consulente -. "Por que eu não posso usar um EntitySet em uma consulta", você pode
Este foi abordados na MSDN fóruns . A essência do raciocínio é que é muito difícil de rastrear objetos adicionados e removidos ao fazer consultas no banco de dados. Em vez disso, o EntitySet é algo de uma cópia local dos objetos relacionados que você pode manipular. Infelizmente, como você percebeu, isso tem o efeito colateral de devolução de expressões em LINQ to Objects chama em vez do LINQ melhor desempenho para SQL.