Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException:数据库操作预计影响 1 行,但实际影响 0 行;

问题描述 投票:0回答:2

当我更新实体时会出现此异常。有时实体会成功更新。

这是我的表实体配置:

使用 EF Core 和 MySQL 作为数据库。

  1. 表1:
    ParentEntity
    Id
    为主键,自增)
  2. 表2:
    ChildEntity
    CId
    为主键且自增,父实体Id为外键)。
  3. 表3:
    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);
c# asp.net-core asp.net-core-webapi
2个回答
1
投票

您可以通过将代码包装在 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),则您会同时多次调用同一个函数。计算该函数被调用了多少次来验证。


0
投票

我遇到了类似的问题,我经常收到此错误:

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: 数据库操作预计会影响 1 行,但实际上 影响 0 行;数据可能已被修改或删除 实体已加载

不同的原因可能导致此错误

但是,如果您的

Child
Subchild
Entity Id
autoIncreament
,并且 IF 您手动为其分配新 Id,则会导致此错误。

所以请确保您没有手动向这些实体添加新的 ID

© www.soinside.com 2019 - 2024. All rights reserved.