Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法使用EF交换两行上的唯一值_C#_Sql Server_Entity Framework_Unique Constraint - Fatal编程技术网

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

C# 无法使用EF交换两行上的唯一值,c#,sql-server,entity-framework,unique-constraint,C#,Sql Server,Entity Framework,Unique Constraint,我试图将唯一列中的值交换为两行(或更多行)。例如: 更新前: 第1行=1 第2行=2 更新后: 第1行=第2行 第2行=1 我正在使用实体框架。这些更改发生在同一上下文的单个提交上。但是,当我尝试此更新时,总是会遇到唯一的约束冲突。EF是否未使用事务 为了完整起见,以下是我的表格设计的一个片段: [FeeSchemeId] UNIQUEIDENTIFIER NOT NULL, [SortPosition] INT NOT NULL, UNIQUE (FeeSchemeId, SortPo

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

更新前:

  • 第1行=1
  • 第2行=2
更新后:

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

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

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

[FeeSchemeId] UNIQUEIDENTIFIER NOT NULL,
[SortPosition] INT NOT NULL,
UNIQUE (FeeSchemeId, SortPosition)
我正在尝试更新“SortPosition”列。这里显示的代码有点复杂,但我可以向您保证,它是同一个上下文,只有一个最终提交。仅当EF尝试写入数据库时才会引发错误

更新:

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

更新2:


事实证明,EF毕竟使用的是单个事务。SQL事件探查器正在将其过滤掉。

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 profiler显示BEGIN TRANSACTION/COMMIT语句

我使用的另一个技巧不依赖于临时值(临时值本身有违反唯一性的风险),即发出一个更新,如下所示:

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

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

“EF是否未使用事务?”-这取决于您正在运行的查询类型()。假设它是一个更新查询(这应该是),它应该将其包装到事务中。您可能必须使其中一个键为空,或者删除并重新插入行(假设这只是一个联接表)。根据SQL探查器。EF正在运行两个单独的语句来更新这两行。能否显示精简版的LINQ查询?此外,即使执行了“两个单独的语句”,事务也在连接上,因此当出现异常时,这两个查询将一起回滚。@tisont。我可以看到,它通过使用一个类似的操作来运行单独的语句,该操作不会对唯一列进行任何更改。SQL Server Profiler仅显式包含事务语句。默认情况下不包括它们。是的,您是对的。在您的例子中,如果EF在显式事务中生成2条update语句,那么SQL Server Profiler应该显示它,那么您可以预期它会起作用。但在同一事务中,SQL Server也不工作……看起来您是对的。我预计,由于所有更改都是在事务期间完成的,SQL Server将根据整体效果而不是单个语句检查约束。SQL不会在事务期间禁用约束。。。这是一种常见的误解。我不认为这是真的,我可以用TSQL中的一条语句交换两个唯一的值。(好吧,也许你不能用两个语句来做,因为中间的东西是无效的,但你可以用一个语句来做。)是的,这是有效的,而且你似乎不能通过EF来做。问题是,若要测试,就不能将原始SQL发送到模拟数据库。