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

Cannot swap unique value on two rows with EF

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

更新前:

更新后:

我正在使用 Entity Framework。这些更改发生在同一上下文的单个提交上。但是,当我尝试此更新时,我总是遇到唯一的约束冲突。 EF没有使用事务吗?

为了完整起见,这里是我的 table 设计的片段:

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

我正在尝试更新 'SortPosition' 列。此处显示的代码有点复杂,但我可以向您保证,它与单个最终提交的上下文相同。仅当 EF 尝试写入数据库时​​才会引发错误。

更新:

- 使用 SQL Server Profiler,我可以看到 EF 是 运行 每个受影响行的单独更新。 EF 不应该对 SaveChanges() 的一次调用使用单个事务吗? -

更新 2:

事实证明 EF 毕竟使用的是单个事务。 SQL Profiler 正在过滤它。

你不能用 2 个语句也用 SQL 服务器来做到这一点。您需要使用第三个值

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 服务器分析器显示 BEGIN TRANSACTION/COMMIT 语句

我使用的另一个不依赖临时值(它们本身有违反唯一性的风险)的技巧是发出单个 UPDATE,如:

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

不幸的是,EF 不够智能,无法自行生成这些类型的语句。