由于外部环境,我的应用程序在更新数据库中的数据然后调用
DbUpdateConcurrencyException
时可能会遇到 dbContext.SaveChangesAsync()
。我正在通过 catch (DbUpdateConcurrencyException)
为自己处理这个异常,然后对这个错误案例做出反应。因此,实体框架不应处理或记录此错误。
不幸的是,EF 似乎在内部记录错误before 我的异常处理程序可以跳入。我尝试按如下方式在 Startup.cs 中配置 DbContext 日志记录,以防止记录
DbUpdateConcurrencyException
,但它没有帮助:
services.AddDbContext<IdentityDbContext>(options =>
{
options
.UseSqlServer(connectionString)
.LogTo(_ => { }, new[] { CoreEventId.OptimisticConcurrencyException });
});
很明显,当
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException
被抛出时,它没有获得CoreEventId.OptimisticConcurrencyException
事件ID,因此不能用它来过滤。还有另一种方法如何禁用DbUpdateConcurrencyException
的日志记录吗?
您可以根据 LogLevel 和 eventId 有条件地记录事件,例如
optionsBuilder.UseSqlServer("Server=(LocalDb)\\MSSQLLocalDB;Database=EfCore7Test;TrustServerCertificate=true;Integrated Security=true",
o =>
{
o.UseRelationalNulls();
})
.LogTo(m => Console.WriteLine(m), (eventId,logLevel) =>
{
//Console.WriteLine($"{eventId.Name} {eventId.Id}");
if (logLevel >= LogLevel.Debug && eventId.Id != 10006) //Microsoft.EntityFrameworkCore.Update.OptimisticConcurrencyException
{
return true;
}
else
{
return false;
}
}
);
不清楚用的是什么logging,但不能
LogTo
。按照这种方法的编写方式,无论如何都不应记录任何内容。 categories
参数用于过滤所有事件。那些匹配的被传递给 action
代表,在这种情况下什么都不记录 _ =>{}
我怀疑应用程序使用了
Microft.Extensions.Logging
。 EF Core Microsoft.Extensions.Logging 页面中解释了这种情况下的过滤。
一种方法是禁止记录特定事件:
options
.UseSqlServer(connectionString)
.ConfigureWarnings(b => b.Ignore(CoreEventId.OptimisticConcurrencyException));
另一个是更改该事件的日志记录级别:
.ConfigureWarnings(
b => b.Log(
(CoreEventId.OptimisticConcurrencyException, LogLevel.Information)));
大多数项目模板生成的
appsettings.json
只记录 Warning
消息及以上的 Microsoft
类别,因此将该事件切换到 Information
应该排除它。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
另一个选项是配置日志记录基础设施如何处理该类别或事件,例如通过更改类别的日志记录级别,排除事件或将其记录到不同的提供者。
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException
没有被CoreEventId.OptimisticConcurrencyException
覆盖,但是得到了基本的事件ID 10000。因此只能通过这个事件ID在.LogTo()
方法中处理。
因为我使用的是 NLog,所以我决定采用另一种方式并在 nlog.config 中禁用特定的记录器:
<logger name="Microsoft.EntityFrameworkCore.Update" minlevel="Error" final="true" />
我在 GitHub 上发布了一个关于它的issue,并说这是一个错误,并且有一个 PR 可以修复它。我认为一旦完成,您的代码就应该可以工作了。