【问题标题】:ASP.NET PUT fails with DbUpdateConcurrencyExceptionASP.NET PUT 失败并出现 DbUpdateConcurrencyException
【发布时间】:2019-04-02 03:50:52
【问题描述】:

我有一个 Web API,它有一个脚手架式的 ApiController。在更新方法(PUT)中,下面的代码段更新了数据库中的实体。

_context.Entry(customers).State = EntityState.Modified;

try
{
    await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
    if (!CustomersExists(id))
    {
        return NotFound("Not found");
    }
    else
    {
        throw;
    }
}

但我发现这只会更新Customer 模型中的属性,它不会传播到引用的实体。例如,有一个 Orders 表,其中存储了每个客户的订单。

public partial class Customers
{
    public Customers()
    {
        Orders= new HashSet<Orders>();
    }

    public string Description { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Orders> Orders { get; set; }
}

因此更新客户的请求也可以更新订单详细信息。但是,

_context.Entry(customers).State = EntityState.Modified; 

如果有更改,此行将无法更新 Orders 表。尝试了很多方法后,我发现,

_context.Customers.Update(customers);

设法成功更新所有内容。但问题是如果当前请求只有 2 个订单,而更新请求有额外的订单(3 个订单),更新又会失败。

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

编辑:没有与数据库的任何连接。所以并发异常是不可能的。

我的 JSON 请求如下所示。

{
   "orders":[
      {
         "id": "1",
         "date": "2018/10/29"
      },
      {
      },
   ],
   "name":"test_name",
   "description":"test_description",
}

我们将不胜感激任何帮助。谢谢。

【问题讨论】:

  • 这是一个数据访问错误。它与 ASP.NET 或脚手架无关。此错误意味着该记录在检索后被其他人(另一个请求?)修改。您必须决定要做什么、重试操作、重新加载记录,或者抛出并警告用户发生了一些奇怪的事情?
  • 检查 EF Core 文档中的 Handling Concurrency Conflicts。它解释了乐观并发的工作原理以及在发生冲突时如何检查更改的内容
  • 我很确定我是唯一使用数据库的人。当我发送POST 请求,获取数据,然后尝试使用额外的order 更新数据集时会发生这种情况。中间没有人访问数据库。
  • 看,你改变了数据。提交客户实体后,为什么不检查所有订单。更新或插入每个订单,完成后更新客户。将其全部包装在事务范围内。

标签: c# entity-framework-core optimistic-concurrency


【解决方案1】:

我遇到了同样的问题。我在一个新项目中使用 EF Core 2。 编辑后操作方法会在任何更新时生成 DbUpdateConcurrencyException

_context.Update(participant);
await _context.SaveChangesAsync();

我不得不用这个替换上面的两行:

var participantToUpdate = await _context.Participants.SingleOrDefaultAsync(p => p.ParticipantID == participant.ParticipantID);
if (await TryUpdateModelAsync<Participant>(participantToUpdate, "", p => p.Nom, p => p.Email))
{
    await _context.SaveChangesAsync();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 2014-05-21
    • 1970-01-01
    相关资源
    最近更新 更多