【问题标题】:Avoid inserting duplicate records in Entity Framework避免在实体框架中插入重复记录
【发布时间】:2014-03-24 18:57:23
【问题描述】:

我有一个典型的场景,用户使用 Entity Framework 6.0 输入插入到 SQL 数据库中的数据。但是,作为实体一部分的某些行需要是唯一的(已经在数据库中通过唯一键约束强制执行)。

为避免可能的并发或性能问题,我倾向于让 SQL Server 完成这些检查。

当尝试保存包含重复行的新实体时,实体框架会引发 DbUpdateException。内部异常是一个 SqlException,它的 Number 等于 2627,以及一条消息:

“违反 UNIQUE KEY 约束‘UK_MyTable_MyRule’。无法在对象‘dbo.MyTable’中插入重复键”。

考虑到涉及多个表,每个表都可能定义了自己独特的约束,没有更好的方法来向用户总结一条更友好的消息:

“名称为 'MyEntity1' 的 MyEntity 已存在。”

...不必通过 SqlException 中的 Number 和 Message 属性推断这一点?

例如:

try
{
    ...
    context.SaveChanges();
}
catch (DbUpdateException exception)
{
    var sqlException = exception.InnerException as SqlException;

    bool isDuplicateInMyTable3 =
        sqlException != null &&
        sqlException.Number = 2627/*Unique Constraint Violation*/ &&
        sqlException.Message.Contains("'UK_MyTable3_");

    if (isDuplicateInMyTable3)
    {
        return "A MyTable3 with " + ... + " already exists.";
    }

    throw exception;
}

是否有一种“更清洁”的方式来实现不涉及查看错误消息字符串的相同功能?

【问题讨论】:

  • 避免插入重复记录的更常用方法可能不是您的首选技术,但这确实意味着您可以自定义您的消息:stackoverflow.com/a/18736484/150342
  • 这也很有趣。谢谢科林。

标签: entity-framework concurrency sqlexception


【解决方案1】:

您可能喜欢使用 AddOrUpdate 方法。 先研究一下。我注意到专家警告过度热心使用。

  Context.Set<TPoco>().AddOrUpdate(poco);

仍然可以抛出其他 EF\DB 异常。 但Duplicate primary key 应该是其中之一。 其他约束问题同上。

【讨论】:

  • 从这里开始研究! thedatafarm.com/data-access/…
  • 感谢科林,我记得 Julie L. 对此提出警告。我自己使用它,但仅用于关键和完整的更新场景。
  • 谢谢菲尔索迪。这似乎是一个不错的方法。但是,我似乎找不到任何关于它的并发性的信息。恐怕我不愿意在我的情况下使用它。
猜你喜欢
  • 2015-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
相关资源
最近更新 更多