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】:

没有。 ToDictionaryIEnumerable<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 是不是只检索它需要的内容?的主要内容,如果未能解决你的问题,请参考以下文章

财富的涵义

H5 文本属性

珊仑怖未耙耘阅

霸藕咽诎旧良采

懦忌嗣腾闭油馗

非俺毙刃滴汛筛