Enumerable.ToDictionary是否只检索它需要的内容?

时间:2010-01-16 21:38:21

标签: linq lazy-evaluation enumerable lazy-sequences todictionary

我正在使用Enumerable.ToDictionary从linq调用创建一个Dictionary:

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 个答案:

答案 0 :(得分:5)

Enumerable.ToDictionary适用于IEnumerable对象。语句的第一部分“(来自...选择术语”)是一个IQueryable对象。 Queryable将查看表达式并构建SQL语句。然后它会将其转换为IEnumerable以传递给ToDictionary()。

换句话说,是的,你的第二个版本会更有效率。

答案 1 :(得分:3)

生成的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是(或只是查看LINQPad的SQL选项卡):

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

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

答案 2 :(得分:1)

没有。 ToDictionaryIEnumerable<T>而不是IQueryable<T>的扩展方法。它不需要Expression<Func<T, TKey>>,而只需要Func<T, TKey>,它会盲目地调用每个项目。它不关心(也不知道)关于LINQ和底层表达式树和类似的东西。它只是迭代序列并构建一个字典。因此,在第一个查询中,将获取所有列。