无法使用EF交换两行上的唯一值

本文关键字:两行 唯一 EF 交换 | 更新日期: 2023-09-27 18:00:38

我正在尝试将唯一列中的值交换为两行(或更多行)。例如:

更新前:

  • 第1行=1
  • 第2行=2

更新后:

  • 第1行=第2行
  • 第2行=1

我使用的是实体框架。这些更改发生在同一上下文的单个提交上。但是,当我尝试此更新时,总是会遇到一个唯一的约束冲突。EF是否未使用交易?

为了完整起见,下面是我的表格设计片段:

[FeeSchemeId] UNIQUEIDENTIFIER NOT NULL,
[SortPosition] INT NOT NULL,
UNIQUE (FeeSchemeId, SortPosition)

我正在尝试更新"排序位置"列。这里显示的代码有点复杂,但我可以向您保证,它与单个最终提交是相同的上下文。只有当EF尝试写入数据库时才会引发错误。

更新:

-

使用SQLServerProfiler,我可以看到EF正在为每个受影响的行运行单独的UPDATE。EF不应该使用单个事务来调用SaveChanges()吗?-

更新2:

事实证明EF毕竟是在使用一笔交易。SQL事件探查器正在筛选它。

无法使用EF交换两行上的唯一值

使用SQL Server时,不能同时使用2条语句。您需要使用第三个值

BEGIN TRANSACTION;
UPDATE MyTable Set Id = 200 where Id = 1;
UPDATE MyTable Set Id = 1 where Id = 2;
UPDATE MyTable Set Id = 2 where Id = 200;
COMMIT;

顺便说一句,SQL Server探查器显示BEGIN TRANSACTION/COMMIT语句

我使用的一个不依赖于临时值(其本身有违反唯一性的风险)的替代技巧是发布单个UPDATE,如:

UPDATE MyTable
SET ID = case when id = 1 then 2 else 1 end
WHERE ID in (1, 2)

不幸的是,EF不够聪明,无法单独生成这些类型的语句。