【问题标题】:How many DbContext subclasses should I have, in relation to my models?相对于我的模型,我应该拥有多少个 DbContext 子类?
【发布时间】:2013-04-13 05:31:12
【问题描述】:

我正在学习 ASP.NET MVC,但我有一些问题,直到现在我阅读的教程还没有以涵盖我的方式进行探索。我试过搜索,但我没有看到任何问题问这个。不过,如果我错过了现有的,请原谅我。

如果我有一个 ASP.NET MVC 应用程序,它有多个模型(其中一些相互关联,一些相互不相关),如果我想使用,我应该创建多少个 DbContext 子类 一个连接字符串和一个一个数据库全局用于我的应用程序?

  • 每个模型都有一个上下文?
  • 每组相关模型都有一个上下文?
  • 所有模型的一个上下文?

如果答案是前两个之一,那么我应该考虑什么以确保为整个应用程序只创建 一个 数据库?我问是因为,在 Visual Studio 中进行本地调试时,在我看来,它创建的数据库与上下文一样多。这就是我发现自己使用第三个选项的原因,但我想知道这是否是正确的做法,或者我是否犯了某种错误,以后会再次出现并咬我。

【问题讨论】:

    标签: asp.net-mvc entity-framework


    【解决方案1】:

    @jrummell 只是部分正确。 Entity Framework 将为每个 DbContext 类型创建一个数据库,如果您将其留给自己的设备。使用 @NeilThompson 从 Julie Lerhman 提到的“有界上下文”的概念,您所做的实际上就是告诉每个上下文实际使用相同的数据库。 Julie 的方法使用通用模式,因此实现它的每个 DbContext 最终都在同一个数据库中,但您可以为每个 DbContext 手动执行,如下所示:

    public class MyContext : DbContext
    {
        public MyContext()
            : base("name=DatabaseConnectionStringNameHere")
        {
            Database.SetInitializer(null);
        }
    }
    

    换句话说,Julie 的方法只是设置了一个基类,您的每个上下文都可以从该基类继承,它会自动处理这部分。

    这做了两件事:1) 它告诉您的上下文使用特定的数据库(即,与所有其他上下文相同)和 2) 它告诉您的上下文禁用数据库初始化。最后一部分很重要,因为这些上下文现在基本上被视为数据库优先。换句话说,您现在没有可以实际导致创建数据库或发出需要进行迁移的信号的上下文。结果,您实际上需要另一个“主”上下文,它将包含应用程序中的每个实体。但是,除了创建迁移和更新数据库之外,您不必将此上下文用于其他任何事情。对于您的代码,您可以使用更专业的上下文。

    另外要记住的是,每个上下文的每个实例都代表一个唯一状态,即使它们共享实体。例如,来自一个上下文的 Cat 实体与来自第二个上下文的 Cat 实体相同,即使它们共享相同的主键。如果您从第一个上下文中检索Cat,更新它,然后尝试通过第二个上下文保存它,您将收到错误消息。该示例有点做作,因为您不太可能在两个不同的上下文中明确拥有相同的实体,但是当您进入外键关系等时,遇到此问题更为常见。即使您没有为相关实体显式声明DbSet,但上下文中的实体依赖于它,EF 也会为它隐式创建DbSet。这就是说,如果您使用专门的上下文,您需要确保它们是真正专门的,并且在任何级别的相关项目上都存在交叉。

    【讨论】:

      【解决方案2】:

      我使用 Julie Lerman 所说的 Bounded Context

      SystemUsers 代码可能与 Products 无关 - 所以我可能有一个 System DbContext 和一个 Shop DbContext(例如)。

      在小型应用程序中使用单一上下文会更轻松,但对于较大的应用程序,它有助于分解上下文。

      【讨论】:

      • 谢谢。我一直在寻找这样的概念。
      【解决方案3】:

      通常,每个数据库应该有一个DbContext。但是,如果您有独立的、不相关的模型组,那么有单独的 DbContext 实现是有意义的。

      在我看来,它正在创建尽可能多的数据库 上下文。

      没错,Entity Framework 将为每个DbContext 类型创建一个数据库。

      【讨论】:

      • 谢谢,您的回答很中肯。不幸的是,我的应用程序只能使用一个数据库。我从您的回答中了解到,这意味着无论如何我都必须使用一个 DbContext 类型,对吗?
      • 不,这只是默认约定。如果您的每个上下文都有相同的连接字符串,它应该可以工作。但是,如果您想使用迁移,则每个上下文都需要一个单独的数据库。
      猜你喜欢
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 2016-01-01
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      • 2016-02-04
      相关资源
      最近更新 更多