清除异常时的实体框架上下文

Posted

技术标签:

【中文标题】清除异常时的实体框架上下文【英文标题】:Clear Entity Framework context on exception 【发布时间】:2017-12-30 23:36:20 【问题描述】:

我正在开发一个 ASP.NET MVC 网站,并且正在使用 Entity Framework 将数据保存/更新到我的数据库中。

我正在使用 ninject 将 dbContext 注入到我的存储库类中,如下所示:

public class MyRepository : IMyRepository

    MyContext _context;

    public MyRepository(MyContext context)
    
        _context = context;
    

    // more code ...

这就是我使用 ninject 注入上下文的方式:

kernel.Bind<MyContext>().ToSelf().InSingletonScope();

我正在使用如下注入的 dbContext 将数据保存到我的数据库中:

public void InsertModel(MyModel r)

    _context.MyModel.Add(r);
    _context.SaveChanges();

现在,我面临的问题是,如果发生异常(例如,如果我故意传递一个无效的模型),Entity Framework 将抛出异常。无效实体保留在 dbContext 中,并且所有进一步的 save 尝试都将因此失败。

我一直在谷歌上搜索这个问题,发现 This Article 建议将 save / update 操作放在 try / catch 块中。如果出现异常,建议清除catch块中的dbContext。

这是正确的方法吗?在每个 save 操作周围放置 try / catch 并清除 dbContext 听起来需要做很多工作?对于解释清除上下文的正确方法,我将不胜感激。

【问题讨论】:

【参考方案1】:

您需要为每个 Web 请求创建一个 dbContext。不要在不同的请求之间共享您的 dbContext:dbContext lifecycle management

dbContext 是轻量级的,创建起来并不昂贵,所以不用担心性能:MSDN

如果您使用 ninject,则可以使用 InRequestScope 代替 InSingletonScopeInRequestScope 将确保您的实体框架 dbContext 的生命周期不超过您的 Http WebRequest 的生命周期,并在每个请求结束时释放您的 dbContext。

kernel.Bind<MyContext>().ToSelf().InRequestScope();

旁注:如果您使用存储库模式,请确保您的存储库也使用 InRequestScope。 Repository 依赖于 dbContext,如果您的 dbContext 在 Repository 仍在使用时被释放,您将遇到问题。

kernel.Bind<IMyRepository>().To<MyRepository>().InRequestScope();

【讨论】:

我遇到了与@Esfandiyar 描述的相同的问题,我尝试使用 InRequestScope(),但无法使其正常工作。我正在使用通用存储库,我的绑定代码是“kernel.Bind(typeof(IGenericRepository)).To(typeof(GenericRepository))”。但是我的上下文并没有根据请求被破坏。对此有何建议? 您是否将 InRequestScope 添加到您的 ninject 绑定中:kernel.Bind(typeof(IGenericRepository)).To(typeof(GenericRepository)).InRequestScope()【参考方案2】:

对于解释清除上下文的正确方法的任何帮助,我们将不胜感激。

您的 DbContext 应限定为单个 Web 请求,并将在请求结束时销毁。

【讨论】:

【参考方案3】:

尝试在出现异常后使用此代码!

foreach (var dbEntityEntry in _context.ChangeTracker.Entries().ToArray()) 
    if (dbEntityEntry.Entity != null) 
        dbEntityEntry.State = Microsoft.EntityFrameworkCore.EntityState.Detached;
    

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于清除异常时的实体框架上下文的主要内容,如果未能解决你的问题,请参考以下文章

了解实体框架启用迁移和上下文

如何使用实体框架关联来自多个上下文的对象

将实体框架与 SQLCE 一起使用时出现奇怪的异常

使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段

实体退出@Transactional上下文时的Spring回调?

使用JSF Converter时的延迟加载异常(指一个集合)