linq IQueryable:是否选择新触发器立即加载?

ntjbwcob  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(118)

我试图理解linq查询是如何执行的。
据我所知,IQueryable查询是在服务器端与过滤器和选择一起计算的,并且只有在调用ToList()First()方法时才执行。
然而,我在理解下面的查询是如何求值的时候遇到了麻烦。“select new”是在客户端求值还是在服务器端求值?
Select(x=> new Note)是否触发了紧急加载?

IQueryable<Note> query = db.Notes
                           .Where(x => Id == someId)
                           .Select(c => new Note 
                                            {
                                                Title = x.Title
                                                Id = x.NoteId,
                                            });
ktecyv1j

ktecyv1j1#

在本例中,Select new是如何将DbDataReader字段Map到Note对象的指令。成员访问部分(如x.Title)被转换为读取器指令(如dbReader.GetString(0))。
LINQ Translator在内部生成用于检索数据的SQL

SELECT 
    x.Title,
    x.NoteId
FROM Notes x
WHERE x.Id = @someId

并生成LambdaExpression(示意图)

(DbDataReader dr) => new Note
{
    Title = dr.GetString(0),
    Id = dr.GetInt32(1)
}

然后编译并缓存此LambdaExpression。当LINQ提供程序通过ToList()ToArray()等执行查询时,生成的SQL将发送到数据库并启动枚举DataReader的进程。对于上面应用的每个DataReader记录,编译lambda。它从IQueryable<Note>(服务器端)到IEnumerable<Note>(客户端)。
这是一个非常简单的解释,说明了引擎盖下所做的工作。

相关问题