【问题标题】:OUTER APPLY is not supported by MySQLMySQL 不支持 OUTER APPLY
【发布时间】:2010-02-25 11:37:52
【问题描述】:

我正在使用带有 MySQL 的实体框架。以下查询导致错误:

var foobar = ctx.ArticleBase.OfType<ActicleSpecial>().Include("CreatedBy.Image.Location").ToList();

错误:“MySQL 不支持 OUTER APPLY”我在稍微不同的查询中也得到“MySQL 不支持 CROSS APPLY”。

我有以下数据模型:

除了 Image 实体具有名为 Location 关系的 Location 实体(一对多关系)之外,UserBase 具有 Image 关系而不是 UserSpecial。

为什么会出现此错误?如何避免这个错误?有可能吗?

【问题讨论】:

  • Oracle 也不支持它:(

标签: mysql entity-framework devart


【解决方案1】:

如果此错误来自 MySQL,则发生以下两种情况之一:

  1. 您没有正确配置提供程序。
  2. 您的 EF 提供程序中存在错误。

如果此错误来自您的 MySQL EF 提供程序,则发生以下两种情况之一:

  1. 您没有正确配置提供程序。
  2. 您的 EF 提供程序存在限制。

SQL 由提供程序生成。您可以通过ProviderManifestToken attribute in EDMX 配置特定于服务器版本的 SQL 生成。这就是您告诉提供者不要使用旧服务器版本不支持的 SQL 功能的方式。

某些 MySQL 存储引擎可能支持其他不支持的 SQL 功能。在这种情况下,提供者需要使用大多数引擎支持的通用功能子集,或者使用ProviderManifestToken 以供您选择。

但是,有缺陷的提供程序也有可能只是返回错误的 SQL。如果是这种情况,那么您必须找到更新或避免涉及错误的查询。

更新:根据@Devart 的回答,这似乎是提供商的限制,这是由于 MySQL 的限制而设计的。 EF 将生成 ADO.NET 规范命令树。将其转换为 SQL 是提供者的责任。如果 EF 在 CCT 中返回一个交叉/外部应用节点,似乎 Devart 还没有找到将其转换为 MySQL 可以处理的 SQL 的方法。因此,要么 MySQL 无法胜任支持所有 EF 查询的任务,要么 MySQL 专家(不是我!)需要向 Devart 展示如何生成与 MySQL 兼容的 SQL,该 SQL 可以正确返回交叉/外部应用的行CCT 节点。

【讨论】:

  • 对不起,克雷格,你错了。这既不是配置错误,也不是 MySQL EF 提供程序中的错误。
  • 这里引用:“在某些情况下,查询管道可能会生成包含 CROSS APPLY 和/或 OUTER APPLY 运算符的 Transact-SQL 语句。因为某些后端提供程序,包括 SQL Server 早于SQL Server 2005,不支持这些运算符,无法在这些后端提供程序上执行此类查询。”这是彼得的情况。我们已经就这个问题联系了 Microsoft,得到的答复是否定的 - 此功能不会更改。
  • @Devart:EF 不产生 T-SQL,句号。 它产生一个 ADO.NET 规范命令树 SqlClient provider 是什么生成 T-SQL。将 SQL 客户端提供程序与非 SQL Server 数据库一起使用当然是一个问题。可能是
【解决方案2】:

这是一个实体框架的内部架构特性。有时它会生成 SQL Server 以外的提供程序不支持的查询。更多信息请访问here at MSDN

【讨论】:

  • 那是错误的。您链接的文章描述了“实体框架的 .NET Framework 数据 SQL Server (SqlClient) 提供程序 中的已知问题”。 (添加了重点。)一个简单的事实是,EF 中的所有 SQL 生成由提供程序完成,而不是 EF 本身。
  • 那么什么是真的?如果提供程序生成 SQL,那么显然您的 MySQL 提供程序存在错误。那么为什么要在 MySQL 中使用 Cross Apply 或 Outer Apply 呢?我应该如何编写查询来避免这个问题?我必须在 Devart 连接器中设置一些东西吗?
  • SQL 是从 EF 查询管道给出的表达式树生成的。如果树中已经包含 OUTER APPLY,则无法在提供程序中删除它。
  • 树将包含System.Data.SqlClient.SqlGen.SqlGenerator.OuterApplyOp 节点,不是 T-SQL 语句!如果提供程序将其转换为服务器无法支持的 SQL,那么这就是提供程序中的错误。如果无法将 CCT 音译为服务器可以支持的 SQL,则不应通过生成服务器不支持的 SQL 来表明这一点!我想知道您是否要重用 System.Data.SqlClient.SqlGen 类型?就目前而言,这样做并没有错,但它是为 T-SQL 硬编码的。这不是 EF 限制!
  • 你又是对的,克雷格。当翻译器遇到 OuterApply 节点且未生成 SQL 时,Devart 提供程序会抛出 NotSupportedException。但是,我们坚持认为此限制是 EF 限制。
猜你喜欢
  • 2015-06-24
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 2017-07-24
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 2019-02-11
相关资源
最近更新 更多