【问题标题】:Composite Unique Update Violation In Entity Framework实体框架中的复合唯一更新冲突
【发布时间】:2018-09-05 16:51:19
【问题描述】:

我有一个具有复合唯一性的表,我会允许用户交换序列号,但 SQL 会引发唯一键冲突。大概是因为每行更改后都会检查违规行为

public class RateCodes
{
   public int Id { get; set; }
   //Unique Composite Key Field 1
   public int Sequence { get; set; }
   //Unique Composite Key Field 2
   public int DivisionId { get; set; }
   public Decimal RateCode { get; set; }
}

在我们的客户端中,我们希望允许用户重新排列其费率代码的顺序。

但是当我执行更新时出现异常

“System.Data.Entity.Infrastructure.DbUpdateException:更新条目时出错。详情请参阅内部异常。

System.Data.Entity.Core.UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。

System.Data.SqlClient.SqlException:违反唯一键约束“UX_RateCodes_Sequence”。无法在对象“dbo.RateCodes”中插入重复键。重复键值为 (346, 3)

尽管我一次保存了所有数据,但 SQL 引发了唯一违规,因为 SQL 在更新所有数据之前执行唯一键验证。

我不想在保存之前删除我的数据,因为其他应用程序可能正在对表进行操作,而我可能没有当前应用程序中的所有数据。我该如何解决这个问题?

【问题讨论】:

  • 为什么不更新现有记录而不是插入新记录然后删除旧记录?
  • @Marathon55 我正在更新现有记录,他们正在抛出一个独特的错误,因为 SQL 在更新所有数据之前执行唯一密钥验证,尽管一次保存了所有数据
  • 您使用的是UpdateRange 方法吗?如果是这样,也许您可​​以循环并一次更新它们。
  • @Marathon55 循环遍历它们会导致同样的问题
  • 所以你有一个现有的记录,Id=346 和 Sequence=3。您想更改该记录的 RateCode 值,对吗?

标签: c# sql entity-framework


【解决方案1】:

我该如何解决这个问题?

如前所述,这不是一个非常容易解决的问题。更新密钥本质上是有问题的,并且唯一约束是不可延迟的。

通过建模解决这个问题的一个简单方法是引入一个新的非关键属性来存储排序。这有一个额外的好处是允许您在排序列中使用小数或浮点数,因此您始终可以在两个现有项目之间插入项目。

另一种思路是用new属性存储待排序,经过一系列更新和删除,发出单

update RateCodes set sequence = sequence_new 
where id = @id and sequence_new is not null

在单个语句中执行记录。您可以使用重新映射值的临时表执行相同的模式。但所有这些都需要一定程度的直接 SQL 编码。

【讨论】:

  • 谢谢,还有一个想法,但是我怎样才能拥有一个唯一的非键属性,由另一个字段分区?
  • 它不会是独一无二的。允许重复使更新变得简单。如果您需要对检索施加完整、稳定的顺序,您可以使用键值来打破平局。
  • 这没有意义,你可能有一个稳定的排序,但它不会使它成为正确的排序。假设在输入重复的序列号时发生更新异常,因此您按键排序,但假设插入顺序可能不正确,但插入顺序是正确的。现在不是抛出错误,而是向该人支付错误的费率
  • 如果您处于控制之中并且您的代码是事务性的,那么异常会如何发生?
  • @Aldert 2人同时更新同一个资源
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多