Domanda

sto usando Enumerable.ToDictionary per creare un Dizionario fuori di una chiamata LINQ:

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

Sarà quella chiamata recuperare la totalità di ogni termine, o sarà recuperare solo l'IDTERM e i campi Nome dal mio fornitore di dati? In altre parole, dovrei essere io stesso salvando il traffico del database se ho invece scritto in questo modo:

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

Soluzione

Enumerable.ToDictionary lavora su oggetti IEnumerable. La prima parte della sua dichiarazione "(da ... selezionare termine") è un oggetto IQueryable. Queryable sta andando a guardare l'espressione e creare l'istruzione SQL. Sarà quindi convertire tale a un oggetto IEnumerable da passare a ToDictionary ().

In altre parole, sì, la tua seconda versione sarebbe più efficiente.

Altri suggerimenti

L'SQL generato restituirà l'intero periodo, così il vostro seconda dichiarazione porterà verso il basso proprio quello che serve.

È possibile impostare dataContext.Log = Console.Out e guardare i diversi risultati della query.

Usando il mio database di LINQPad di esempio, ecco un esempio:

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();

L'SQL generato è (o semplicemente sbirciare scheda SQL di 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]

No. ToDictionary è un metodo di estensione per IEnumerable<T> non IQueryable<T>. Non ci vuole un Expression<Func<T, TKey>> ma semplicemente un Func<T, TKey> che chiameremo alla cieca per ogni elemento. Non si preoccupa (e non sa) su LINQ e le sottostanti alberi di espressione e cose del genere. E 'appena itera la sequenza e si accumula un dizionario. Di conseguenza, nella prima query, tutte le colonne sono inverosimile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top