Enumerable.ToDictionary 是不是只检索它需要的内容?
Posted
技术标签:
【中文标题】Enumerable.ToDictionary 是不是只检索它需要的内容?【英文标题】:Does Enumerable.ToDictionary only retrieve what it needs?Enumerable.ToDictionary 是否只检索它需要的内容? 【发布时间】:2011-01-05 22:40:31 【问题描述】:我正在使用 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);
【问题讨论】:
【参考方案1】:没有。 ToDictionary
是 IEnumerable<T>
而不是 IQueryable<T>
的扩展方法。它不需要Expression<Func<T, TKey>>
,而只是Func<T, TKey>
,它会盲目地调用每个项目。它不关心(也不知道)LINQ 和底层表达式树之类的东西。它只是迭代序列并建立一个字典。因此,在您的第一个查询中,所有列都被提取。
【讨论】:
【参考方案2】:生成的 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]
【讨论】:
【参考方案3】:Enumerable.ToDictionary 适用于 IEnumerable 对象。您的语句“(from ... select term”) 的第一部分是一个 IQueryable 对象。 Queryable 将查看表达式并构建 SQL 语句。然后它将其转换为 IEnumerable 以传递给 ToDictionary()。
换句话说,是的,您的第二个版本会更有效率。
【讨论】:
以上是关于Enumerable.ToDictionary 是不是只检索它需要的内容?的主要内容,如果未能解决你的问题,请参考以下文章