清除异常时的 Entity Framework 上下文

Clear Entity Framework context on exception

我正在 ASP.NET MVC 网站上工作,并且正在使用 Entity Framework 将 save/update 数据存入我的数据库。

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

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 听起来像很多工作?对于解释清除上下文的正确方法的任何帮助,我将不胜感激。

Would appreciate any help on explaining the correct approach for clearing the context.

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

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

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

如果您正在使用 ninject,则可以使用 InRequestScope 而不是 InSingletonScopeInRequestScope 将确保您的 Entity Framework dbContext 的生命周期不超过您的 Http WebRequest 的生命周期,并在每个请求结束时处理您的 dbContext。

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

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

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

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

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