【问题标题】:how can i disable unique constraints when savechanges in entity framework在实体框架中保存更改时如何禁用唯一约束
【发布时间】:2017-08-24 15:04:12
【问题描述】:

我在 Entity Framework 6 和 SQL Server 中遇到了一个有趣的问题。

我们有一个带有复合键的表。这是一个例子;

ID  Col1  Col2
--  ----  ----
1   1     1
2   1     2
3   2     1
4   2     2
5   2     3

因此,Col2 对于每个 Col1 都是唯一的。我需要交换 2 个值以产生所需的结果...

ID  Col1  Col2
--  ----  ----
1   1     2
2   1     1

我正在使用实体框架,从数据库加载对象,进行更改,然后调用 SaveChanges。

我收到异常:“违反 UNIQUE KEY 约束 'UQ_TableA_Constraint1'。无法在对象 'dbo.TableA' 中插入重复键。”

据说,SaveChanges 在事务中被调用。 EF Source 似乎表明它是,失败的更新是原子的这一事实表明这是有效的。但是,更新似乎也是逐行完成的,即使在事务内部也是如此。因此,EF 首先对记录 1 执行更新,这会暂时产生重复的唯一键。

有没有办法缓解这种情况?我宁愿不更新到临时值,调用 savechanges,然后更新到正确的值,因为这可能会失败并使数据处于不正确的状态。

有什么选择吗?

【问题讨论】:

标签: sql entity-framework


【解决方案1】:

希望我能理解您的问题。
在事务内部也必须满足约束,这是 SQL Server(和其他 DBMS)行为而不是 EF 行为。
您可以在事务中使用临时值来确保一切顺利。
如果您需要运行更新查询(对多条记录),您可以使用外部库 https://github.com/loresoft/EntityFramework.Extended(但如果我理解您的问题,您将不会解决约束问题)。

【讨论】:

  • 谢谢。我想我知道这一点,但需要确认。然而这很奇怪,因为这似乎是一件合乎逻辑的事情。复合键实际上不是 100% MY 的问题;我只是认为这更容易解释。在我的 REAL 问题中,我们在 Col2 中为 Col1 中的每个值提供了一个唯一值列表,这些值是唯一但无序的。但是 col2 中的 1 值被标记为默认值。然后我们有一个唯一约束,它返回 -1 作为默认值,或者 col2 值不是默认值,这确保只有 1 个默认值。
  • 如果我将具有较晚 ID 的记录(即表结构向下)更新为默认值,它可以工作。这是因为在更新期间所有默认值都是错误的。但是,如果我在表堆栈上设置一个更高的值(即具有较低的 ID 值),它会失败,大概是因为它在更新期间将 2 个值设置为默认值。将 all 设置为 false、保存更改然后应用默认值的唯一问题是,如果第二次更新失败,将没有默认值。
  • SQL Server 不支持延迟约束,例如Postgres。因此,使用临时值并将您的更新序列包装在单个事务中。如果您将更新包装在事务中,则数据将永远不会处于错误状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-23
  • 2013-09-24
  • 1970-01-01
  • 2019-11-11
  • 2017-03-20
  • 2019-03-02
相关资源
最近更新 更多