当我更新实体时会出现此异常。有时实体会成功更新。
这是我的表实体配置:
使用 EF Core 和 MySQL 作为数据库。
ParentEntity
(Id
为主键,自增)ChildEntity
(CId
为主键且自增,父实体Id为外键)。SubChildEntity
(SId
为主键且自增,CID
作为外键)。错误:
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException:数据库操作预计影响1行,但实际影响0行;自加载实体以来,数据可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=527962。
在 Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyExceptionAsync(RelationalDataReader reader,Int32 commandIndex,Int32 ExpectedRowsAffected,Int32 rowsAffected,CancellationToken CancellationToken)
在 Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithRowsAffectedOnlyAsync(Int32 commandIndex,RelationalDataReader reader,CancellationToken CancellationToken)
代码:
var Entity = await _context.Parent
.Include(x => x.Child)
.ThenInclude(x => x.SubChild)
.FirstOrDefaultAsync(x => x.Id == Id, cancellationToken);
// Some values to update in parent, child and sub child entities.
_context.Parent.Update(Entity);
var result = await _context.SaveChangesAsync(cancellationToken);
您可以通过将代码包装在 try catch 块中来调试它。在捕获中,您可以查看数据库值以及建议的更新。这在处理并发冲突中有所介绍。
例如:
try {
//Your original code
var Entity = await _context.Parent
.Include(x => x.Child)
.ThenInclude(x => x.SubChild)
.FirstOrDefaultAsync(x => x.Id == Id, cancellationToken);
// Some values to update in parent, child and sub child entities.
_context.Parent.Update(Entity);
var result = await _context.SaveChangesAsync(cancellationToken);
}
catch (DbUpdateConcurrencyException ex)
{
//The code from Microsoft - Resolving concurrency conflicts
foreach (var entry in ex.Entries)
{
if (entry.Entity is Person)
{
var proposedValues = entry.CurrentValues; //Your proposed changes
var databaseValues = entry.GetDatabaseValues(); //Values in the Db
foreach (var property in proposedValues.Properties)
{
var proposedValue = proposedValues[property];
var databaseValue = databaseValues[property];
// TODO: decide which value should be written to database
// proposedValues[property] = <value to be saved>;
}
// Refresh original values to bypass next concurrency check
entry.OriginalValues.SetValues(databaseValues);
}
else
{
throw new NotSupportedException(
"Don't know how to handle concurrency conflicts for "
+ entry.Metadata.Name);
}
}
}
将您的提议值与数据库值进行比较,以查看差异以及可能导致冲突的原因。
根据提供的信息,我的预感是,如果在 Web api 或其他一些多线程应用程序中使用同一个函数(或者可能使用某种重试库,如 Polly),则您会同时多次调用同一个函数。计算该函数被调用了多少次来验证。
我遇到了类似的问题,我经常收到此错误:
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: 数据库操作预计会影响 1 行,但实际上 影响 0 行;数据可能已被修改或删除 实体已加载
不同的原因可能导致此错误
但是,如果您的
Child
或 Subchild
Entity Id 是 autoIncreament
,并且 IF 您手动为其分配新 Id,则会导致此错误。
所以请确保您没有手动向这些实体添加新的 ID