为啥 EF 为简单查询生成子查询?

Posted

技术标签:

【中文标题】为啥 EF 为简单查询生成子查询?【英文标题】:Why EF generating a sub-query for a simle query?为什么 EF 为简单查询生成子查询? 【发布时间】:2012-10-02 13:02:21 【问题描述】:

有一个简单的 Linq to EF:

var query = from p in _db.Posts
            where p.BlogtId == blogId
            select p;

它以这种形式生成 SQL:

SELECT
`Extent1`.`PostId`, 
`Extent1`.`BlogId`, 
...
FROM `Posts` AS `Extent1`
 WHERE `Extent1`.`BlogId` = @p__linq__0

但是当我向这个查询添加订单时

var query = from p in _db.Posts
            where p.BlogId == blogId
            orderby p.PublishDate
            select p;

它生成这个查询

SELECT
`Project1`.`PostId`, 
`Project1`.`BlogId`, 
...
FROM (SELECT
`Extent1`.`PostId`, 
`Extent1`.`BlogId`, 
...
FROM `Posts` AS `Extent1`
 WHERE `Extent1`.`BlogId` = @p__linq__0) AS `Project1`
 ORDER BY 
`Project1`.`PublishDate` ASC

为什么会生成一个子查询?这个查询在 mysql 中存在性能问题。 MySQL 正在尝试执行内部查询,该查询会拉回数据库中的所有记录,然后尝试对主题进行排序。

我需要一个解决方案来通过 linq 生成下面的 sql

SELECT
`Extent1`.`PostId`, 
...
FROM `Posts` AS `Extent1`
 WHERE `Extent1`.`BlogId` = @p__linq__0
 ORDER BY 
`Extent1`.`PublishDate` ASC

【问题讨论】:

为什么要把它们全部拉回来——它们被过滤掉了? 我看不出这应该比您建议的查询慢多少。 EF 版本读起来很尴尬,我承认。它在子查询中非常明确地过滤,然后对最终结果集进行排序。也许这是 LINQ 确保 RDBMS 在过滤之前不对所有结果进行排序的方式?您的索引设置是否正确?每个查询的一些性能指标如何? EF 不生成 SQL。它生成一个 ADO.NET CCT。您的 MySQL 提供程序会生成 SQL。询问提供者的作者为什么它会生成 MySQL 处理不好的 SQL。 @CraigStuntz 请阅读这个帖子social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/… 问:还有一个问题,这个问题是与MySql Data provider 相关还是来自EntityFramework/Linq 的Core 到实体? A:这个和EF有关,如果可能的话,我建议你以后升级版本,最新的版本会更有效。 :) @GhootiFarangi:我再说一遍:EF 不生成 SQL;您的 MySQL 提供程序可以。 EF 对 MySQL 的 SQL 语法一无所知。那来自提供者。我看到一个 MS 的人有点暗示不是这样,但这并不是真的。 【参考方案1】:

这不是实体框架问题,尽管您的链接可能会告诉其他人。它与 MySqlConnector/net 有关。我可以证明!啊,没想到吧。

使用 MSSQL 数据库和System.Data 连接器连接这个确切的场景,您将看到格式正确的 SQL。这是 MySqlConnector 内部的投影问题。如果你想修复它,那就自己进去编辑吧。

这里是如何拥有一个本地编辑的 MySqlConnector/net 副本:How to customize MySql Connector/net?

【讨论】:

以上是关于为啥 EF 为简单查询生成子查询?的主要内容,如果未能解决你的问题,请参考以下文章

实战 EF(LINQ) 如何以子查询的形式来 Join

如果子查询没有返回结果,为啥“= ALL(子查询)”评估为真?

EF如何包含要查询的子对象

为啥 EF 在分离时会删除子实体?

为啥我的 Access Max() 子查询不起作用?

EF6 Linq 查询。仅包括返回子表的第一个条目