WebAPI + EF5,实体框架无法从DBUpdateException中恢复,并且需要完全重新启动该服务

时间:2013-05-31 17:52:40

标签: asp.net-web-api entity-framework-5

我的数据库中有两个表。表USER和表USER_ADDRESSES

表USER具有UserID,UserName,HumanName

表USER_ADDRESSES具有UserAddresseID,UserID,Address

这两个表通过UserID外键相关联。

我首先使用代码。 POCO正如人们所期望的那样:

Public class User
{
    Public guid UserID {get;set;}
    Public string UserName {get;set;}
    Public string HumanName {get;set;}

}

Public class UserAddress
{
    Public guid UserAddressID {get;set;}
    Public guid UserID {get;set;}
    Public string Address {get;set;}

    Public virtual User User {get;set;}
}

如果我POST一个用户,它会流经EF并进入物理数据库 - 酷

如果我使用正确分配为上述用户的UserID的UserID外键POST一个UserAddress,则userAddress通过EF流入物理数据库 - 完美。

现在,当我正在学习这门课程时,我喜欢测试我知道会导致错误的场景......了解某些事情的失败往往会带来更多的理解(恕我直言)。

为此,我重复上述步骤。发送一个用户,然后POST一个地址,但这次使用Address.UserID属性中的空GUID,我知道会导致SQL服务器出错,这次EF获取一个错误从数据库和表面发回我的控制器类中的错误作为DbUpdateException,我接着发送回BadRequest ErrorResponse,这没关系,除非现在我可以向DB发送任何内容,如果我随后尝试发布新用户EF在每个POST上抛出一个DbUpdateException。摆脱这种情况的唯一方法是停止调试WebAPI项目,杀死IISExpress并重新启动所有内容。

我怀疑它与dbset.Local中跟踪的实体有关。看来这个集合很乐意存储违反数据库约束的实体,甚至在DB抛出错误之后,EF也不会删除故障实体从它的缓存,我想每次我调用DataContext.SaveChanges()时,EF都会继续尝试提交它的bdset.Local属性中的Faulty地址实体,从而阻止我向DB提交任何进一步的东西,直到整个重新启动项目并刷新各种dbset.Local集合。

好的我明白了,在我的控制器类中,我可以通过在将对象提交到我的repository / UnitOfWork之前评估对象的各种属性来防止其中的一些问题,从而防止它们首先进入dbset.Local,也许我可以添加一些装饰到我的POCO,如果UserAddress == Guid.Empty在UserAddress实体中,ModelState.IsValid返回false 。但是肯定EF应该能够从DB发起的错误中恢复,这样如果INSERT语句在针对SQL服务器运行时失败,EF应该从其跟踪对象的本地缓存中删除错误实体。从而防止整个系统需要完全重启。这样做的结果是,如果我对其他非关键字段有唯一约束,在我尝试提交实体之前,我将不得不查询数据库以确保数据库中没有任何记录会导致抛出DBUdateException ,这种方法对我来说似乎效率低下。我宁愿接受错误并将其丢回客户端供他们考虑。

现在也许我有责任在发生DbUpdateException时做一些事情来从dbset.Local集合中删除故障实体或类似的东西。如果是这样的话,我应该怎么做呢?

正如我写这篇文章一样,我想知道:EF是否无法从自己的DBUdateExceptions中恢复!无需重启IIS。或者我应该在没有任何限制的情况下构建我的数据库,并允许客户在那里放置任何旧垃圾。我相信EF实体跟踪应该遵守db约束并防止出现故障的实体首先进入dbset。

请指导我从DBUpdateException恢复的正确方法吗?

0 个答案:

没有答案