在MVC Web App中跨存储库共享DbContext

时间:2013-02-27 13:31:19

标签: asp.net-mvc ef-code-first repository-pattern dbcontext service-layer

问题

在MVC Web应用程序中跨多个存储库共享EF DbContext的正确方法是什么?这样做是否谨慎/必要,做或不做的陷阱是什么?

背景

假设:

  • App.MvcSite (数十个控制器,多个区域等)
  • App.Services (服务层,多项服务)
  • App.Data (许多存储库等)
  • 为了简单起见,
  • ...等被排除在外(EF Code First latest)

迄今为止的研究

我似乎在SO和互联网上找到了至少两三个思想流派。

  1. 将您的DbContext共享/范围扩展到请求,以便单个请求具有所有存储库共享的单个DbContext。
  2. 在服务层共享/范围DbContext - 该服务维护单个DbContext并根据需要将其传递到每个存储库。
  3. 不要共享DbContext,因为它们很便宜让每个Repo都有自己的。
  4. 在一个小型网站中,这是一个非问题,这就是为什么大多数MS和社区的例子根本不解决这个问题。

    根据我的经验,到目前为止我还没有使用过有限的存储库。我一直有服务使用DbContext并直接更改它所以我不需要担心这一点。我被告知,从单元测试的角度来看,有限的存储库有很大的好处......我们将看看它是否值得其余部分。

    我的想法

      

    (1)将您的DbContext分享/范围扩展到请求

    这很有意思,因为它巧妙地避免了单例上下文的陷阱,一些开发人员认为这是一个答案,但发现DbContext不能那样工作。但它似乎有一个缺点,它假设所有存储库,服务等将在整个请求中协调......通常情况并非如此,对吧?如果一个仓库在另一个仓库完成其工作之前保存了更改,该怎么办? (外(内(内)))

      

    (2)在服务层分享/范围您的DbContext

    这对我来说更有意义,因为每项服务都应该协调一个特定的工作单元(小写有意)。因此,如果在一个请求中使用了多个服务,那么每个服务都有自己的数据库上下文是正确的(如果不是必需的话)。

      

    (3)不要共享DbContext,因为它们很便宜

    这是我一直这样做的方式......实际上我几乎总是每个请求只有一个DbContext,因为只有一个服务被调用。有时它可能是两个,因为两个服务由一个协调工作的控制器调用。但鉴于我目前的应用程序,有许多有限的存储库,每个存储库都有自己的上下文,这意味着给定的请求可能有3-10个DbContext实例。我认为(可能是错误的)这是有问题的。


    重复问题:

    在MVC Web应用程序中跨多个存储库共享EF DbContext的正确方法是什么?这样做是否谨慎/必要,做或不做的陷阱是什么?

2 个答案:

答案 0 :(得分:5)

  • DbContext便宜,但分布式交易不便宜。
  • 附加到一个上下文的对象不能在另一个上下文中使用(如果你有对象关系)

分享上下文的最简单方法是开始使用控件容器的反转:http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci

答案 1 :(得分:1)

我会考虑前两个选项的组合以及关于你对第一个选项的看法,不要让存储库保存任何更改(这不是推荐的做事方式,Martin Fowler说他自己)和他介绍了工作单元模式。