Enumerable.ToDictionary только получает то, что ему нужно? - PullRequest
4 голосов
/ 17 января 2010

Я использую Enumerable.ToDictionary для создания словаря на основе вызова linq:

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

Будет ли этот вызов извлекать полноту каждого термина или он получит только поля TermID и Nameот моего поставщика данных?Другими словами, я бы сэкономил трафик базы данных, если бы вместо этого написал это так:

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

Ответы [ 3 ]

5 голосов
/ 17 января 2010

Enumerable.ToDictionary работает с объектами IEnumerable. Первая часть вашего утверждения "(из ... выберите термин") является объектом IQueryable. Queryable собирается посмотреть на выражение и построить оператор SQL. Затем он преобразует это в IEnumerable для передачи в ToDictionary ().

Другими словами, да, ваша вторая версия будет более эффективной.

3 голосов
/ 17 января 2010

Сгенерированный SQL вернет весь термин, поэтому ваше второе утверждение обрушит именно то, что вам нужно.

Вы можете установить dataContext.Log = Console.Out и посмотреть на различные результаты запроса.

Используя мой пример базы данных LINQPad, вот пример:

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

Сгенерированный SQL (или просто загляните на вкладку SQL 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]
1 голос
/ 17 января 2010

Нет. ToDictionary - это метод расширения для IEnumerable<T>, а не IQueryable<T>. Это не Expression<Func<T, TKey>>, а просто Func<T, TKey>, которое он будет слепо вызывать для каждого предмета. Его не волнует (и он не знает) о LINQ и нижележащих деревьях выражений и тому подобное. Он просто повторяет последовательность и создает словарь. Как следствие, в вашем первом запросе все столбцы извлекаются.

...