c# - 如何在没有显式引用的情况下访问打开的 DbContext?

标签 c# asp.net asp.net-mvc entity-framework

我使用 Entity Framework 已经有一段时间了,我遇到过几个场景,其中两个上下文会尝试访问同一个实体等,所以我想知道我是否没有打开/以最好的方式关闭我的数据库上下文。

目前,我基本上按照最初设置基本 MVC 应用程序的方式在我的每个 Controller 上打开一个 DbContext,这意味着我在 Controller 上有一个私有(private) dbcontext 字段,并且我覆盖了 Controller 的 dispose 方法以在上下文中调用 dispose .

然而,有时我也会在我的其他一些类中对数据库进行查询,这些类可以从 Controller 内部调用, Controller 也有一个打开的上下文。

有没有办法在没有显式处理程序的情况下访问开放上下文?通过十几种不同的方法传递 DbContext 引用对我来说真的没有意义。

最佳答案

使用依赖注入(inject)

正如其他人所说并且可能会重申的那样,“正确的方式”通常被认为是依赖注入(inject)。

在我最近的项目中,我组织了一些事情,所以我几乎完成了项目,DI 非常轻松,以至于我自己做(而不是使用注入(inject)器)。其中一个主要因素是相当严格地遵守这种结构:

                           WebProject
                             |    |
                             |   DataServices
                             |    |        | 
                           ViewModels    EntityModels

在一个工作单元期间,通过单个 DataServiceFactory 实例访问所有数据服务,这需要一个 MyDbContext 实例。另一个因素是完全 RESTful 应用程序设计 - 这意味着我不必在我的代码中散布持久性功能。

没有依赖注入(inject)

也就是说,也许 DI 不适合您这个项目。也许:

  • 您不打算编写单元测试
  • 你需要更多时间来理解 DI
  • 您的项目结构已经深度集成了 EF

在 ASP.NET MVC 中,工作单元通常与请求生命周期完全一致 - 即 HttpContext.Current。因此,您可以根据请求懒惰地实例化存储库“单例”,而不是使用 DI。这是一个经典的单例模式,将当前上下文作为后备存储,用于保存您的 DbContext:

public class RepositoryProxy {
    private static HttpContext Ctx { get { return HttpContext.Current; } }
    private static Guid repoGuid = typeof(MyDbContext).GUID;

    public static MyDbContext Context {
        get {
            MyDbContext repo = Ctx.Items[repoGuid];
            if (repo == null) {
                repo = new MyDbContext();
                Ctx.Items[repoGuid] = result;
            }
            return repo;
        }
    }

    public static void SaveIfContext() {
        MyDbContext repo = Ctx.Items[repoGuid];
        if (repo != null) repo.SaveChanges();
    }
}

如果您觉得特别懒惰,您也可以自动SaveChanges(您仍然需要手动调用它来检查副作用,当然,比如检索新项目的 id) :

public abstract class ExtendedController : Controller {
    protected MyDbContext Context {
        get { return RepositoryProxy.Context; }
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext) {
        RepositoryProxy.SaveIfContext();
        base.OnActionExecuted(filterContext);
    }
}

关于c# - 如何在没有显式引用的情况下访问打开的 DbContext?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29083548/

相关文章:

c# - 在 C# 中没有获得正确的日期时间格式

c# - 传递参数时sqldatasource的问题

asp.net-mvc - angularjs 使用 asp.net mvc 进行端到端测试

html - MVC 2 - 我有一个使用大量 HTML 的控件。我该如何提高性能?

c# - 需要解决方法 : notify a user that exe is missing dependencies from within the application?

c# - 为什么 Math.Round() 不支持 float ?

c# - 使用 Powershell 以编程方式清除回收站

c# - 具有自定义端点名称的 WEB API .NET 操作

asp.net - 你调用的对象是空的。

jquery - 使用 ASP.NET MVC Url.Action 在 JQuery 中生成链接