我正在尝试将两个(或更多行)的唯一列中的值交换。例如:
更新前:
更新后:
我正在使用Entity Framework。这些更改发生在同一上下文的单个提交中。但是,当我尝试此更新时,我总是会遇到一个独特的约束违规。 EF没有使用交易吗?
为了完整起见,这是我的表格设计的片段:
[FeeSchemeId] UNIQUEIDENTIFIER NOT NULL,
[SortPosition] INT NOT NULL,
UNIQUE (FeeSchemeId, SortPosition)
我正在尝试更新'SortPosition'列。这里显示的代码有点复杂,但我可以向您保证,它与单个最终提交的上下文相同。只有在EF尝试写入数据库时才会抛出该错误。
更新
- <德尔> 使用SQL Server Profiler我可以看到EF为每个受影响的行运行单独的UPDATE。如果EF没有使用单个事务来调用SaveChanges()吗? 德尔> -
更新2:
毕竟EF正在使用单个事务。 SQL事件探查器正在过滤它。
答案 0 :(得分:3)
使用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;
BTW,SQL Server探查器显示BEGIN TRANSACTION / COMMIT语句
答案 1 :(得分:2)
我使用的另一个不依赖于临时值(它本身就有违反唯一性的风险)的技巧是发出一个UPDATE,如下所示:
UPDATE MyTable
SET ID = case when id = 1 then 2 else 1 end
WHERE ID in (1, 2)
不幸的是,EF不够聪明,不能单独生成这些类型的语句。