c# - 如何使用 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 编写相同的代码?
解决方案
当然。只需标记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。
推荐阅读
- php - 用 PHP 解析非常简单的 XML
- mysql - 错误的 SQL 语法...找不到列“COUNT(status)”
- python - 如何在主窗口中更改 PyQt5 目录视图的大小?
- javascript - 使用nodejs意外令牌在bash脚本中执行java程序for循环
- c# - 增加“PropertyInfo SetValue”
- c# - WPF RichTextBox 中的项目符号列表在发送到 Outlook 时显示非常小的项目符号
- r - R for循环中不区分大小写的搜索
- android - 如何在 Cloud Firestore 中获取随机 ID?
- javascript - ng-mouseleave 但带有键盘
- perl - HTTP::Daemon::SSL 自动获取并提供中间证书