在 EF Core 5.0 中使用 FromRawSql 会引发异常

Posted

技术标签:

【中文标题】在 EF Core 5.0 中使用 FromRawSql 会引发异常【英文标题】:Using FromRawSql in EF Core 5.0 throws an exception 【发布时间】:2021-12-10 22:36:04 【问题描述】:

我在 EF Core 5.0 中有一个实体 (DTO),PK 类型为 Guid,带有 mysql DB 的 Pomelo 连接器。 PK 在 MySql 中映射为 binary(16)。

例如:

this.DbContext.Set<TEntity>().FromSqlRaw(@"select * from <TableName> Id = 0;)", Id).ToList()

错误:

MySqlConnector.MySqlException (0x80004005):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以了解在 '= _binary'ٗ?^?K??V˧??';) 附近使用的正确语法;)

想知道这是否是由于不兼容的类型匹配 Guid binary(16)?

这会引发 Sql 解析异常(全栈):

Microsoft.EntityFrameworkCore.Query: Error: An exception occurred while iterating over the results of a query for context type 'DocuSign.Adm.Agreements.Data.AgreementDbContext'.
MySqlConnector.MySqlException (0x80004005): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= _binary'ٗ?^?K??Vݧ??';)
) AS `a`
LEFT JOIN (
    SELECT `a0`.`PartyId`,' at line 3
   at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in /_/src/MySqlConnector/Core/ResultSet.cs:line 50
   at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 135
   at MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 444
   at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 60
   at MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 314
   at MySqlConnector.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior) in /_/src/MySqlConnector/MySqlCommand.cs:line 256
   at System.Data.Common.DbCommand.ExecuteReader()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()

MySqlConnector.MySqlException (0x80004005): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= _binary'ٗ?^?K??Vݧ??';)
) AS `a`
LEFT JOIN (
    SELECT `a0`.`PartyId`,' at line 3
   at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in /_/src/MySqlConnector/Core/ResultSet.cs:line 50
   at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 135
   at MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 444
   at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 60
   at MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 314
   at MySqlConnector.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior) in /_/src/MySqlConnector/MySqlCommand.cs:line 256
   at System.Data.Common.DbCommand.ExecuteReader()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
'this.DbContext.Set<TEntity>().FromSqlRaw(@"select * from agreements ParentId = 0;)", parentId).ToList()' threw an exception of type 'MySqlConnector.MySqlException'
    Data: System.Collections.ListDictionaryInternal
    ErrorCode (System.Runtime.InteropServices.ExternalException): -2147467259
    ErrorCode: ParseError
    HResult: -2147467259
    HelpLink: null
    InnerException: null
    IsTransient: false
    Message: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= _binary'\bٗ?^?K\u000f??Vݧ?\u0006?';)\r\n) AS `a`\r\nLEFT JOIN (\r\n    SELECT `a0`.`PartyId`,' at line 3"
    Number: 1064
    Source: "System.Private.CoreLib"
    SqlState: "42000"
    StackTrace: "   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at MySqlConnector.Core.ResultSet.<ReadResultSetHeaderAsync>d__2.MoveNext() in /_/src/MySqlConnector/Core/ResultSet.cs:line 50\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 137\r\n   at MySqlConnector.MySqlDataReader.<CreateAsync>d__97.MoveNext() in /_/src/MySqlConnector/MySqlDataReader.cs:line 445\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at MySqlConnector.Core.CommandExecutor.<ExecuteReaderAsync>d__0.MoveNext() in /_/src/MySqlConnector/Core/CommandExec
utor.cs:line 60\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()\r\n   at MySqlConnector.MySqlCommand.<ExecuteReaderAsync>d__75.MoveNext() in /_/src/MySqlConnector/MySqlCommand.cs:line 314\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at MySqlConnector.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior) in /_/src/MySqlConnector/MySqlCommand.cs:line 256\r\n   at System.Data.Common.DbCommand.ExecuteReader()\r\n   at Mic
rosoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)\r\n   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)\r\n   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)\r\n   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()\r\n   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)"
    TargetSite: Void Throw()
    m_data: System.Collections.ListDictionaryInternal

【问题讨论】:

请分享实际失败的SQL语句 【参考方案1】:

您似乎忘记了 WHERE 关键字。 这应该工作

this.DbContext.Set<TEntity>().FromSqlRaw(@"select * from <TableName> where Id = 0;)", Id).ToList()

【讨论】:

@Rafabd 除此之外,如果您在不使用命令参数的情况下制作动态 SQL 语句,您可能需要考虑使用 FromSqlInterpolated() 而不是 FromSqlRaw()。请参阅Raw SQL Queries: Passing parameters 了解更多信息。

以上是关于在 EF Core 5.0 中使用 FromRawSql 会引发异常的主要内容,如果未能解决你的问题,请参考以下文章

EF Core (< 5.0) HasComputedColumnSql - 在插入/更新或 SQL Server/AzureSQL 上的每个查询上计算?

EF Core 5.0 添加多对多使得一对多无法确定

EF Core 5.0 - 更改“定义查询”映射实体时是不是需要生成迁移?

EF Core 5.0 中的多对多关系是不是可以配置为仅保留一个导航属性(在一侧)?

为 ASP.NET Core 5.0 - EF Core 5.0 Web App 配置 PostgreSQL 连接字符串以在 MS 或 Linux 云上运行?

.NET Core 5.0 EF Migration 添加新的外部列