c# - 通过 Entity Framework 更新时如何绕过唯一键约束(使用 dbcontext.SaveChanges())

标签 c# .net sql-server asp.net-mvc entity-framework

我在通过 EF 更新一些数据时遇到了问题。

假设我的数据库中有一个表:

Table T (ID int, Rank int, Name varchar)

我在 Rank 上有一个唯一的键约束。

例如,我在表中有这样的数据:

Link to example data image

我的 C# 对象是这样的:Person (name, rank),因此在前端,用户想要切换 Joe 和 Mark 的级别。

当我通过 EF 进行更新时,由于唯一 key 而出现错误。
我怀疑这是因为 dbContext.SaveChanges 使用了这种风格的更新:

UPDATE Table SET rank = 5 where Name = Joe
UPDATE Table SET rank = 1 where Name = Mark

通过 SQL 查询,我可以执行此更新:

从 C# 端将用户定义的表(等级、名称)传递到查询中,然后:

  update T 
  set T.Rank = Updated.Rank
  from Table T 
  inner join @UserDefinedTable Updated on T.Name = Temp.Name

并且这不会触发唯一键约束

但是我想使用 EF 进行此操作,我该怎么做?

到目前为止,我已经想到了这些其他解决方案:

  • 删除旧记录,通过 EF 从更新的对象中添加"new"记录

  • 放弃对数据库的唯一约束并编写 C# 函数来完成唯一约束的工作

  • 只需像上面的示例一样使用 SQL 查询而不是 EF

注意:我上面使用的表结构和数据只是一个例子

有什么想法吗?

最佳答案

想法 - 你可以将它作为两步操作(包装为单个事务)

1) 将所有必须更新的实体的值设置为负数(Joe, -1; Mark -5)

2) 设置为正确的值(Joe,5,Mark 1)


SQL Server 的等价物:

SELECT 1 AS ID, 1 AS [rank], 'Joe' AS name INTO t
UNION SELECT 2,2,'Ann'
UNION SELECT 3,5,'Mark'
UNION SELECT 4,7,'Sam';

CREATE UNIQUE INDEX uq ON t([rank]);

SELECT * FROM t;

/* Approach 1
UPDATE t SET [rank] = 5 where Name = 'Joe';
UPDATE t SET [rank] = 1 where Name = 'Mark';

Cannot insert duplicate key row in object 'dbo.t' with unique index 'uq'.
The duplicate key value is (5). Msg 2601 Level 14 State 1 Line 2
Cannot insert duplicate key row in object 'dbo.t' with unique index 'uq'.
The duplicate key value is (1).
*/

BEGIN TRAN
-- step 1

UPDATE t SET [rank] = -[rank] where Name = 'Joe';
UPDATE t SET [rank] = -[rank] where Name = 'Mark';


-- step 2
UPDATE t SET [rank] = 5 where Name = 'Joe'
UPDATE t SET [rank] = 1 where Name = 'Mark';
COMMIT;

db<>fiddle demo

关于c# - 通过 Entity Framework 更新时如何绕过唯一键约束(使用 dbcontext.SaveChanges()),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56818151/

相关文章:

sql - 嵌套查询或连接

sql - 合并以更新所有目标表列

c# - 将通用类型检查(工厂式模式)改进为更面向 SOLID?

c# - 对 C# 中的 "override"与 "new"感到困惑

c# - 转换 VB.NET --> C# 项目

c# - 如何使用 Unity 从配置文件注入(inject)构造函数参数

c# - System.Web.HttpException 与 BasicAuthentication 自定义 HttpModule

c# - 如何将 Javascript 日期时间转换为 C# 日期时间?

sql-server - 如何使用密码保护我的 SQL Server 数据库?

c# - 带有控件的表单级别的 KeyPress