linq-to-sql - 为什么在实体框架查询上使用 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)
由于我相信这段代码足够通用,可以在任何情况下工作,我想知道是否
- 我是否正确理解正在发生的事情?
- 为什么它没有像 和 那样作为通用解决方案
ToDictionary
实施?ToArray
ToList
解决方案
没有Queryable.ToDictionary
方法(在此处查看),因此ToDictionary
采用context.Set<Post>()
as IEnumerable
。这意味着,正如您正确理解的那样,context.Set<Post>()
首先评估然后在内存中进行处理。
这是非常低效的,因为现在对于 each Post
,评论由单独的查询加载,如果启用了延迟加载,否则Post.Comments
是null
.
因此,投影到匿名类型是有效执行此操作的唯一选择。
推荐阅读
- python - 操作错误:无法打开数据库文件(自动化)
- regex - 将正则表达式匹配转换为字符串
- python - 如何删除由类方法函数生成的数据框中的重复元素?
- r - 如何将参数传递到使用 Rscript 中的 argparse 的 R 脚本中
- python - 在 cplex python api 中编写优化约束时出错
- javascript - 尽管主题和生产者都存在,但无法发送 Kafka 消息
- docusignapi - OAuth 调用的 Docusign 速率限制是多少?
- html - HTML5 音频 -- DOMException: 该元素没有支持的来源
- javascript - 在反应或javascript中以模态显示味精
- r - 使用 dplyr 有一种方法可以保留行但将空白添加到选定的重复值