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 IQueryables e IEnumerables, 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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top