Asp.net web api WebAPI+;实体框架不会从DBUpdateException恢复,需要完全重新启动服务

Asp.net web api WebAPI+;实体框架不会从DBUpdateException恢复,需要完全重新启动服务,asp.net-web-api,entity-framework-5,Asp.net Web Api,Entity Framework 5,我的数据库中有两个表。表用户和表用户地址 表用户具有UserID、UserName和HumanName 表USER_ADDRESSES包含UserAddresseID、UserID和Address 这两个表通过UserID外键相互关联 我先做代码。POCO正如人们所预料的那样,我猜: Public class User { Public guid UserID {get;set;} Public string UserName {get;set;} Public stri

我的数据库中有两个表。表用户和表用户地址

表用户具有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;}
}
如果我发布一个用户,它将通过EF进入物理数据库-酷

如果我发布一个UserAddress,并将UserID外键正确分配为上述用户的UserID,那么UserAddress将通过EF流入物理数据库-perfect

现在,当我学习这门课程时,我喜欢测试我知道会导致错误的场景……了解某些事情如何失败通常会导致更好的理解(IMHO)

为此,我重复上述步骤。 发布一个用户,然后发布一个地址,但这次Address.UserID属性中的GUID为空,我知道这会导致SQL server出错, 这次EF从DB返回一个错误,并将该错误作为DbUpdateException显示在我的控制器类中,然后我将其发送回一个BadRequest ErrorResponse,这将很好,除非现在我无法向DB发布任何内容,如果我随后尝试发布新用户,EF会在每次发布时抛出一个DbUpdateException。摆脱这种情况的唯一方法是停止调试WebAPI项目,杀死IISExpress并重新启动所有程序

我怀疑这与dbset中被跟踪的实体有关。Local似乎此集合乐于存储违反数据库约束的实体,即使在DB抛出错误后,EF也不会从其缓存中删除出现故障的实体,我猜每次调用DataContext.SaveChanges()时,EF一直试图提交它的bdset.Local属性中存在的错误地址实体,从而阻止我向DB提交任何进一步的内容,直到整个项目重新启动并刷新各个dbset.Local集合

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

现在,我的责任可能是在发生DbUpdateException时,从dbset.Local集合或类似集合中删除出现故障的实体。如果是这样的话,我该怎么办

在我写这篇文章的时候,我一直在想:EF是否应该不能从DBUdateExceptions中恢复!?无需重新启动IIS。或者我应该不受任何约束地构建数据库,允许客户在其中放置任何旧垃圾。我认为EF实体跟踪应该遵守db约束,并首先防止出现故障的实体进入dbset


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

听起来您正在共享相同的数据库上下文betwern请求,是吗?您应该为每个请求创建一个新的db上下文。这样,不管任何可能的问题的真正原因是什么,问题都局限于导致问题的请求。换句话说,无论在一个请求中发生了什么不好的事情,它永远不会影响其他请求。是的,我是,或者更确切地说是。我一直在关注EFMVC项目,我看到作者正在使用一个数据库工厂来服务一个单例上下文:我最初认为我们必须保持上下文温暖,以提高对数据库的后续调用的性能。但事实证明,这是ObjectCOntext的工作,正如我在这里否认的那样,DBContext似乎是UnitOfWork的实现,这意味着实现我自己的UnitOfWork是多余的