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