首页 > 解决方案 > 如何使用 EF Core 更新具有并发控制的行?

问题描述

我有一个表“订单”,其中包含以下列:“Id”、“ProductId”、“Status”、“Version”。

每次更改行后,“版本”都会增加 1。此列用于控制多个用户更改的并发性。

例如,我读取了一个 Id=3 和 Version=7 的订单。当我更新它时,我必须确保没有人更改此行。通过 SQL,我会编写这样的脚本:

UPDATE Orders
SET Status = 'completed', Version = Version + 1
WHERE Id = 3 AND Version = 7

如何在不使用 SQL 命令的情况下通过 EF Core 编写相同的代码?

标签: c#.netentity-framework-core

解决方案


当然。只需标记Version并发令牌,其更新前的值将用于WHERE任何更新的子句中。例如

modelBuilder.Entity<Order>()
            .Property(o => o.Version)
            .IsConcurrencyToken(true);

对于像这样的改变

var order = ...
order.Status = "Completed";
order.Version += 1;
db.SaveChanges();

UPDATE 看起来像这样:

  SET NOCOUNT ON;
  UPDATE [Events] SET [Status] = @p0, [Version] = @p1
  WHERE [Id] = @p2 AND [Version] = @p3;
  SELECT @@ROWCOUNT;

并且如果Version已更改 0 行将受到影响,EF 将抛出一个 DbUpdateConcurrencyException指示并发冲突

您还可以通过附加配置使用服务器端递增的并发令牌,或者使用特定于提供程序的类型,如 SQL Server 的rowversion


推荐阅读