【问题标题】:Is base.OnModelCreating(modelBuilder) necessary?base.OnModelCreating(modelBuilder) 是必要的吗?
【发布时间】:2016-09-19 14:53:35
【问题描述】:

我覆盖了OnModelCreating,在方法中有base.OnModelCreating(modelBuilder);这一行

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
}

查看有关如何实现此功能的代码示例和手册,我对是否需要它感到困惑。有时它在那里,有时不在那里。有时在方法的开头,有时在结尾。

我该怎么处理它?

【问题讨论】:

    标签: entity-framework entity-framework-6


    【解决方案1】:

    根据documentation,直接继承DbContext类也没关系:

    当派生上下文的模型已初始化时,但在模型已被锁定并用于初始化上下文之前,将调用此方法。 此方法的默认实现什么都不做,但它可以在派生类中被覆盖,这样模型就可以在锁定之前进一步配置。

    换句话说,由于 根据定义,is 没有任何作用,因此调用 base.OnModelCreating 是不必要的,但同时调用也不会受到伤害 - 这就是为什么 有时它在那里,有时它不是。有时在方法的开头,有时在结尾。

    【讨论】:

    • 我明白了。尽管如此,为什么它什么都不做时会调用它?我的意思是,我知道覆盖提供了模型构建器,我们可以在其中放置更多配置。但是为什么要调用base?或者换句话说,我们传递给它的模型构建器会发生什么。听起来一切……没用:-)
    • 这就是重点。当你有一个基本的virtual 方法时,必须有一些文档解释在你覆盖它时调用该方法的要求,比如你是否需要调用它,是否需要在开头或开头调用它结尾。这里的文档说明该方法什么都不做,所以没有要求 - 如果你愿意,你可以在覆盖的任何地方调用它,或者你根本不能调用它。一旦你知道它根据定义什么都不做,你可能不会叫它:)
    • 在 OO 中,您调用基类以确保满足其声明的行为。无论这种行为是什么。您不会详细查看 base 的功能。也许有一天它决定做一些其他的事情,然后什么都不做,或者以不同的方式什么都不做。因此我会称之为。但是,将其放在首位还是放在最后的问题仍然存在。
    • 在使用 ASP.Net Identity 的 ASP.Net 项目中是必需的。
    • @BenjaminRay 是的,它是 - 当您继承一些 IdentityDbContext 基类时。这里我说的是DbContext 类。每个用作基类的派生类都应定义是否需要基类调用以及是在覆盖代码之前还是之后。
    【解决方案2】:

    这是Pawel Kadluczka - MSFT 所说的...

    目前这并不重要。 OnModelCreating 和 Seed 方法没有任何实现(即 函数是空的)在它们的基类中。因此调用 基类基本上是无操作的。我不认为有任何计划 改变它(特别是对于种子方法 - 我们如何知道要哪些数据 放入数据库?)

    一般来说,受保护的方法可以在基类中有一些实现 类。在这种情况下,这取决于从 这样一个类来决定他/她是否想利用 基类的方法中提供的功能与否。如果 开发人员认为他/她只想在 他/她将调用的基类中的方法提供的功能 进入这个方法。否则她/他不会调用 基类,并将提供所有必需的功能 派生类的方法。

    参考: Link

    【讨论】:

    • 一个人(是否是 MSFT)说什么真的无关紧要。唯一重要的是 官方文档 所说的内容(如果它是错误的,那么这是一个必须报告和修复的错误 - 显然这里不是这种情况)。
    • hmm..两者在这里都一样 :D @IvanStoev
    【解决方案3】:

    当您覆盖创建时,您也覆盖了身份创建的创建。如果您没有继承任何 IdentityDbContext,则不需要它,但如果您使用了 Identity,那么您也必须调用身份的实现。因此,要调用身份的实现,请使用 base.OnModelCreating(builder);因此,如果您覆盖 Identity 的创建,那么 Identity 将丢失其配置。所以你运行基础来保存身份的创建。

    【讨论】:

      【解决方案4】:

      我刚刚开始了一个 ASP.NET MVC5 项目,并且基于这个线程我注释掉了“base.OnModelCreating(modelBuilder)”。 然后我想为 EF6 标准 DbContext 更新表名等,并且在执行“add-migration Abc”时,控制台不断向我抛出这个错误:

      在模型生成过程中检测到一个或多个验证错误:

      xxx.Models.IdentityUserRole: : EntityType 'IdentityUserRole' 没有定义键。定义此 EntityType 的键。 xxx.Models.IdentityUserLogin: : EntityType 'IdentityUserLogin' 没有定义键。定义此 EntityType 的键。 IdentityUserRoles:EntityType:EntitySet 'IdentityUserRoles' 基于没有定义键的类型'IdentityUserRole'。 IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' 基于没有定义键的类型'IdentityUserLogin'。

      经过一番挣扎,我尝试取消注释“base.OnModelCreating(modelBuilder)”,这使得一切都按预期工作。

      我还没有找到确切的原因,但似乎这行代码在某些情况下是必要的。

      【讨论】:

      • 您是继承自DbContext 还是IdentityDbContext?这可能会有所作为。
      • @Sinjai:在这个特定的项目中,我继承自 IdentityDbContext。最后,这个类继承自 DbContext 定义 OnModelCreating 的地方,所以我仍然不完全清楚它的用途,但如果它需要迁移工作,这是我现在可以忍受的一个谜:-)
      • 就可以了。正如所选答案正确指出的那样,DbContext 不提供OnModelCreating() 的实现,但IdentityDbContext 提供。因此,如果您不在子类中调用 base.OnModelCreating(),则不会配置身份关系(因此可能会导致错误),正如您所发现的那样。
      猜你喜欢
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多