首页 > 解决方案 > 为什么在实体框架查询上使用 ToDictionary 时会收到 NullReferenceException?

问题描述

我很惊讶,似乎我的 lambda 表达式是作为 C# 代码执行的,而不是被转换为 SQL。

如果真的是这样,那就有点可惜了。例如:

context.Set<Post>().ToDictionary(post => post.Id, post => post.Comments.Count())

这段代码显然会首先将帖子加载到 C# 对象中,然后计算评论。我得出这个结论是因为在一段类似的真实世界代码中,我有一个 NullReferenceException因为post.Comments为空(请注意,在我的代码中,在执行这行代码之前加载的帖子没有关系)Comments

使用它会更有效:

context.Set<Post>()
    .Select(post => new { Key = post.Id, Value = post.Comments.Count() })
    .ToDictionary(entry => entry.Key, entry => entry.Value)

由于我相信这段代码足够通用,可以在任何情况下工作,我想知道是否

标签: linq-to-sqlentity-framework-6

解决方案


没有Queryable.ToDictionary方法(在此处查看),因此ToDictionary采用context.Set<Post>()as IEnumerable。这意味着,正如您正确理解的那样,context.Set<Post>()首先评估然后在内存中进行处理。

这是非常低效的,因为现在对于 each Post,评论由单独的查询加载,如果启用了延迟加载,否则Post.Commentsnull.

因此,投影到匿名类型是有效执行此操作的唯一选择。


推荐阅读