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

Linq Enumerable.ToDictionary是否只检索它需要的内容?,linq,lazy-evaluation,enumerable,lazy-sequences,todictionary,Linq,Lazy Evaluation,Enumerable,Lazy Sequences,Todictionary,我正在使用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字段?换言之,如果我改为这样写,是否

我正在使用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);

否。
ToDictionary
IEnumerable
而不是
IQueryable
的扩展方法。它不需要一个
表达式
,只需要一个
Func
,它会盲目地为每个项目调用它。它不关心(也不知道)LINQ和底层表达式树之类的东西。它只是迭代序列并建立一个字典。因此,在第一次查询中,将获取所有列。

生成的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选项卡):


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

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

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

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