Pergunta

Estou usando enumerável.Todictionary para criar um dicionário de uma chamada LINQ:

return (from term in dataContext.Terms
        where term.Name.StartsWith(text)
        select term).ToDictionary(t => t.TermID, t => t.Name);

Essa chamada buscará a totalidade de cada termo ou só recuperará o termo e os campos de nome do meu provedor de dados? Em outras palavras, eu estaria salvando -me de tráfego de banco de dados se o escrevesse assim:

return (from term in dataContext.Terms
        where term.Name.StartsWith(text)
        select new { term.TermID, term.Name }).ToDictionary(t => t.TermID, t => t.Name);
Foi útil?

Solução

Enumerável.Todictionary trabalha em objetos ienumerable. A primeira parte da sua declaração "(do ... Selecionar termo") é um objeto iQueryable. O consultável analisará a expressão e construirá a instrução SQL. Em seguida, ele converterá isso para um iEnumerable para passar para o TDICIário ().

Em outras palavras, sim, sua segunda versão seria mais eficiente.

Outras dicas

O SQL gerado retornará o período inteiro, para que sua segunda declaração derrubará exatamente o que você precisa.

Você pode definir dataContext.Log = Console.Out e observe os diferentes resultados da consulta.

Usando meu banco de dados LINQPAD de amostra, aqui está um exemplo:

var dc = (TypedDataContext)this;

// 1st approach
var query = Orders.Select(o => o);
dc.GetCommand(query).CommandText.Dump();
query.ToDictionary(o => o.OrderID, o => o.OrderDate).Dump();

// 2nd approach
var query2 = Orders.Select(o => new { o.OrderID, o.OrderDate});
dc.GetCommand(query2).CommandText.Dump();
query2.ToDictionary(o => o.OrderID, o => o.OrderDate).Dump();

O SQL gerado é (ou apenas espiar na guia SQL do Linqpad):

// 1st approach
SELECT [t0].[OrderID], [t0].[OrderDate], [t0].[ShipCountry]
FROM [Orders] AS [t0]

// 2nd approach
SELECT [t0].[OrderID], [t0].[OrderDate]
FROM [Orders] AS [t0]

Não. ToDictionary é um método de extensão para IEnumerable<T> não IQueryable<T>. Não é preciso um Expression<Func<T, TKey>> mas simplesmente um Func<T, TKey> que ele chamará cegamente para cada item. Não se importa (e não sabe) sobre o LINQ e as árvores de expressão subjacente e coisas assim. Isso apenas itera a sequência e cria um dicionário. Como conseqüência, em sua primeira consulta, todas as colunas são buscadas.

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