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

时间:2015-07-01 02:53:39

标签: c# sql-server entity-framework unique-constraint

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

更新前:

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

更新后:

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

我正在使用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事件探查器正在过滤它。

2 个答案:

答案 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不够聪明,不能单独生成这些类型的语句。