我正在将 ASP.NET Core Web API 与 Entity Framework Core (pomelo) 结合使用。我有一个 MariaDB 数据库。我按照模板使用 Swagger UI 来探索我的 API。当我尝试使用它删除一行时,出现以下错误:
Microsoft.EntityFrameworkCore.DbUpdateException:保存实体更改时发生错误。有关详细信息,请参阅内部异常。
MySqlConnector.MySqlException (0x80004005):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,了解在第 3 行“RETURNING 1”附近使用的正确语法
在 //src/MySqlConnector/Core/ServerSession.cs 中的 MySqlConnector.Core.ServerSession.ReceiveReplyAsync(IOBehavior ioBehavior,CancellationToken CancellationToken):第 894 行 在 //src/MySqlConnector/Core/ResultSet.cs 中的 MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior):第 37 行 在 //src/MySqlConnector/MySqlDataReader.cs 中的 MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken CancellationToken) 处:第 130 行 在 //src/MySqlConnector/MySqlDataReader.cs 中的 MySqlConnector.MySqlDataReader.InitAsync(CommandListPosition commandListPosition,ICommandPayloadCreator PayloadCreator,IDictionary`2 cachedProcedures,IMySqlCommand 命令,CommandBehavior 行为,活动活动,IOBehavior ioBehavior,CancellationToken CancellationToken):第 4 行83 在 //src/MySqlConnector/Core/CommandExecutor.cs 中的 MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(CommandListPosition commandListPosition、ICommandPayloadCreator PayloadCreator、CommandBehavior 行为、活动活动、IOBehavior ioBehavior、CancellationToken CancellationToken):第 56 行 在 //src/MySqlConnector/MySqlCommand.cs 中的 MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior 行为,IOBehavior ioBehavior,CancellationToken CancellationToken):第 357 行 在 /_/src/MySqlConnector/MySqlCommand.cs 中的 MySqlConnector.MySqlCommand.ExecuteDbDataReaderAsync(CommandBehavior 行为,CancellationToken CancellationToken)处:第 350 行 在Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject参数对象,CancellationToken取消令牌) 在Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject参数对象,CancellationToken取消令牌) 在 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection 连接,CancellationToken 取消令牌)
删除应该在我的控制器和存储库中处理,如下所示:
[HttpDelete("alertId")]
public async Task<IActionResult> DeleteAlert(int alertId)
{
var alert = await _dataRepository.GetAlertAsync(alertId);
if (alert is null)
{
return NotFound("Alert not found");
}
await _dataRepository.DeleteAlertAsync(alert);
return NoContent();
}
还有这个
public class AlertRepository (IrtsContext context) : IDataRepositoryAlerts
{
readonly IrtsContext _alertContext = context;
public async Task DeleteAlertAsync(Alert entity)
{
if (entity != null)
{
_alertContext.Remove(entity);
await _alertContext.SaveChangesAsync();
}
else
{
throw new NotImplementedException();
}
}
}
我不明白这一点。我相信是我的
dbContext
处理“保存实体更改”。 SQL 语法错误怎么办?我在代码中找不到“Returning 1”。
我尝试在数据库中手动删除该行。这样可行。 所有其他操作(GET、POST 和 PUT)都可以正常工作。
我尝试用保持点运行它以查看错误发生的位置,但一切似乎都执行没有问题。
我很感激任何提示。我显然对此很陌生;)
编辑:MariaDB 版本 11.2.2 Edit2:这是我的警报类:
public partial class Alert
{
public int AlertId { get; set; }
public DateTime? Zeitpunkt { get; set; }
public string? Quelle { get; set; }
public string? AlertStatus { get; set; }
public string? AlertTyp { get; set; }
public string? BetroffeneSysteme { get; set; }
public virtual ICollection<Vorfall> Vorfalls { get; set; } = new List<Vorfall>();
}
这是它的实体配置:
modelBuilder.Entity<Alert>(entity =>
{
entity.HasKey(e => e.AlertId).HasName("PRIMARY");
entity
.ToTable("alert")
.HasCharSet("utf8mb4")
.UseCollation("utf8mb4");
entity.Property(e => e.AlertId)
.HasColumnType("int(11)")
.HasColumnName("AlertID");
entity.Property(e => e.AlertStatus).HasMaxLength(255);
entity.Property(e => e.AlertTyp).HasMaxLength(255);
entity.Property(e => e.BetroffeneSysteme).HasMaxLength(255);
entity.Property(e => e.Quelle).HasMaxLength(255);
entity.Property(e => e.Zeitpunkt).HasColumnType("datetime");
});
edit3:我找到了参数化查询。事情是这样的: 【sql查询日志中的错误】
编辑 4:将查询复制到工作台中会出现以下错误:
看来问题确实出在“RETURNING 1”上,我必须承认我不知道它的用途。有办法去除吗?我发现无法编辑 EF 查询本身。或者我可能需要尝试不同的数据库。 谢谢您的帮助!
根据您的调查,我怀疑您的数据库版本比您想象的要旧。您可以尝试将
ServerVersion.AutoDetect(connectionString)
添加到 EF core MySql 配置中。看看这是否会影响 EF core 编写您的数据库版本可以理解的 SQL?当您配置服务时,它看起来像这样:
builder.Services.AddDbContext<ApplicationContext>(options =>
{
//...your other configs
var connectionString = builder.Configuration.GetConnectionString("or however you get the connection string...");
options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
});