防止实体框架在使用 Include 时添加 ORDER BY

Posted

技术标签:

【中文标题】防止实体框架在使用 Include 时添加 ORDER BY【英文标题】:Prevent Entity Framework adding ORDER BY when using Include 【发布时间】:2014-08-26 11:29:00 【问题描述】:

我们有一个类似于以下的查询:

from x in db.Table.Include(x => x.Parent)
                  .Include(x => x.Parent.Relation)
                  .Include(x => x.Relation)
                  .Include(x => x.Children)
where /* some query */
select x

问题在于,当添加.Include(x => x.Children) 时,Entity Framework 添加到生成的 SQL 中的 ORDER BY 语句会导致查询需要很长时间才能执行 - 如下所示:

ORDER BY [Project2].[Id1] ASC, [Project2].[Id2] ASC, [Project2].[Id] ASC, [Project2].[C4] ASC

在 linq 查询中添加 orderby 也无济于事,除了添加一个额外的列来排序之外,它不会影响上面的语句。

【问题讨论】:

也许问题应该是:EF为什么要添加ORDER BY?我认为它需要将查询结果拆分为用于创建包含类型的部分。 EF 可能希望数据库引擎比 CLR 代码更有效地进行排序(通过索引)。我很确定没有办法摆脱它。 同意阿诺德。您可以尝试在 Children 上创建索引。实际上,order by 不应该使查询减慢那么多... 问题是即使使用手写查询,如果没有在查询中指定要排序的列,SQL 会假定它应该按子表的主键排序,从而导致查询速度非常慢,并发出警告 @987654326 @ 因为它试图对子表中的所有行进行排序。 如果您在使用 ORM 时遇到性能问题或疑虑,您可能需要考虑使用 SP。这是您在性能和优化方面拥有灵活性的唯一方法 我在漫长的职业生涯中学到的是,无论项目如何,都不应该使用 EF 或任何其他疯狂的 ORM。考虑用 Dapper 重写所有东西,真的很好。 【参考方案1】:

显然,这是 EF 在内部执行的操作,以简化之后生成的对象的创建。您不能删除 order by 指令。

【讨论】:

只要有时间和金钱,你可以做任何事情。 当然,但我认为 OP 不愿意重新编码实体框架。

以上是关于防止实体框架在使用 Include 时添加 ORDER BY的主要内容,如果未能解决你的问题,请参考以下文章

添加实体时如何防止添加相关实体?

在将实体框架对象图序列化为 Json 时防止 ***Exception

实体框架:如何防止 dbcontext 被多个线程访问?

如何使用带有代码优先实体框架的 UnitOfWork 模式防止重复条目?

尝试添加项目时在实体框架中出现错误

使用实体框架添加记录时违反链接记录的PRIMARY KEY约束