Pregunta

Estoy usando Enumerable.ToDictionary para crear un diccionario al lado de una llamada LINQ:

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

¿Será que la llamada se ha podido recuperar la totalidad de cada término, o será sólo recuperar el los campos Nombre de mi proveedor de datos y TermID? En otras palabras, ¿estaría ahorrando mismo tráfico de la base de datos si por el contrario lo escribí así:

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

Solución

Enumerable.ToDictionary funciona en objetos IEnumerable. La primera parte de su declaración "(de ... seleccione término") es un objeto IQueryable. Consultable se va a ver en la expresión y la construcción de la instrucción SQL. A continuación, convertir que a un IEnumerable para pasar a ToDictionary ().

En otras palabras, sí, su segunda versión sería más eficiente.

Otros consejos

El SQL generado devolverá la totalidad del plazo, por lo que su segunda declaración hará bajar justo lo que necesita.

Puede establecer dataContext.Log = Console.Out y mirar los diferentes resultados de la consulta.

Uso de mi base de datos LINQPad muestra, he aquí un ejemplo:

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

El SQL generado es (o simplemente vistazo a la pestaña SQL de 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 es un método de extensión para IEnumerable<T> no IQueryable<T>. No hace falta ser un Expression<Func<T, TKey>> sino simplemente un Func<T, TKey> que va a llamar a ciegas para cada elemento. No le importa (y no sabe) sobre LINQ y los árboles de expresión subyacentes y cosas por el estilo. Es simplemente itera la secuencia y se acumula un diccionario. Como consecuencia de ello, en su primera consulta, todas las columnas se recuperan.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top