EF CodeFirst在保存更改时处理数据库异常

Gor*_*ran 5 entity-framework entity-framework-4 ef-code-first

由于EF不支持唯一键约束,因此我们需要在Save方法期间捕获异常,并向用户显示错误消息.

这种方法的问题是:

  • 我们怎么知道哪条记录引发了异常
  • 我们怎么知道什么样的问题引发了异常(例如,我可以在同一条记录上有两个独特的约束,所以我需要告诉用户哪一个被破坏了)

DBMS是SqlServer 2008.

如何解决这些问题?

Sla*_*uma 2

如果您允许用户输入在数据库中必须唯一的值,您应该在保存更改之前验证此输入:

if (context.Customers.Any(c => c.SomeUniqueProperty == userInput))
    // return to user with a message to change the input value
else
    context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

这不仅适用于数据库中具有唯一约束的值,而且适用于输入必须引用现有目标记录或主键值(如果数据库中未自动生成主键)的外键值。在后一种情况下,EF 也无法为您提供帮助,因为上下文不知道整个数据库表的内容,而只知道当前附加到上下文的实体。确实,EF 将禁止附加两个具有相同主键的对象,但允许两个对象具有相同的唯一键约束。但是,当您将更改保存到数据库时,这并不能完全防止主键约束违规。

在不太可能的情况下,在Any检查和SaveChanges另一个用户输入具有相同值的记录之间,我会认为发生的异常无法处理,只是告诉用户“发生了预期的错误,请重试...”。如果用户再次尝试,Any检查会再次发生,他将收到更有用的消息来更改上面代码中的输入值。

针对此类唯一键约束或主键约束违规返回的异常是一般性的DbUpdateException,内部异常之一将SqlException包含 SQL Server 错误代码作为其属性之一。任何其他详细信息只能在异常消息“违反 UNIQUE KEY 约束 IX_SomeUniqueProperty_Index... ”或类似消息中找到。如果您希望用户能够理解此信息并做出相应反应,您可以显示它。否则,您可以记录此消息,以便管理员或开发人员检查可能的错误或其他问题。