我将 ASP.NET Core 6 Web API 升级到 .NET 8.0。
在
Signin
页面,我有以下代码:
public async Task<IActionResult> LoginAttempt([Bind("Email","Password","PingIdPin","SelectDeviceMessage","SelectDevice","CollectPinMessage","CollectPin","MultipleDevices","MultipleDevicesYesNo","ChallengeId","UserPrompt","LoginFailed")] LoginModel loginModel)
{
// more snippets of the code
Microsoft.AspNetCore.Identity.SignInResult result = new();
try
{
result = await _signInManager.PasswordSignInAsync(user, password, false, false);
}
catch (Exception ex)
{
string ss = ex.Message;
_logger.LogInformation(-999000001, "{0} ... result = await _signInManager.PasswordSignInAsync(user, password, false, false); [{1}]", nameof(Login), ex.Message);
}
}
我得到这个例外:
EntityFrameworkCore.DbUpdateException:Microsoft.EntityFrameworkCore.DbUpdateException:'无法保存更改,因为目标表具有数据库触发器。请相应地配置您的表,请参阅 https://aka.ms/efcore-docs-sqlserver-save-changes-and-output-clause 了解更多信息。'
SqlException:如果该语句包含不带 INTO 子句的 OUTPUT 子句,则 DML 语句的目标表“AspNetUsers”不能有任何启用的触发器。
我将 Entity Framework Core 的所有 Nuget 包升级到 8.0.8。
的屏幕截图使用.NET 6.0,它可以无缝运行。不确定升级到 .NET 8.0 时缺少什么。
请让我知道如何解决这个问题。
这是新版本 EF Core 中的设计初衷。请参阅文档页面 带有触发器或某些计算列的 SQL Server 表现在需要特殊的 EF Core 配置,错误消息本身会将您链接到:
旧行为
以前版本的 SQL Server 提供程序通过一种效率较低的技术保存更改,但该技术始终有效。
新行为
默认情况下,EF Core 现在通过显着更高效的技术保存更改; 不幸的是,如果目标表具有数据库触发器或某些类型的计算列,则 SQL Server 不支持此技术。有关更多详细信息,请参阅 SQL Server 文档。
[...]
缓解措施
从 EF Core 8.0 开始,可以显式配置是否使用“OUTPUT”子句。例如:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .ToTable(tb => tb.UseSqlOutputClause(false)); }
在 EF7 或更高版本中,如果目标表有触发器,那么您可以让 EF Core 知道这一点,EF 将恢复到以前的效率较低的技术。这可以通过配置相应的实体类型来完成,如下所示:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .ToTable(tb => tb.HasTrigger("SomeTrigger")); }
请注意,执行此操作实际上并不会让 EF Core 以任何方式创建或管理触发器 - 它当前仅通知 EF Core 表上存在触发器。因此,可以使用任何触发器名称。 指定触发器可用于恢复旧行为,即使表中实际上没有触发器。
(粗体强调我的)
在该页面上进一步阅读,查看一个代码示例,用于选择退出all模型表的新技术,而不是依赖于每个表的缓解措施。
相关:SQL Server:检索数据库生成的值时优化 SQL Server OUTPUT 子句的使用#27372 - 有关该问题的早期 GitHub 错误报告
相关:SaveChanges、数据库触发器和不支持的计算列 - Microsoft 文档页面,涵盖 SQL Server 的各种注释