【问题标题】:How do I allow the EF4 CodeFirst database initializer to run under development, but not run in production如何允许 EF4 CodeFirst 数据库初始化程序在开发中运行,但不在生产中运行
【发布时间】:2011-03-25 13:47:50
【问题描述】:

我正在尝试在线部署我的第一个 Alpha 版系统,以供少数人开始使用。在开发过程中,我大量使用DropCreateDatabaseOnModelChange<TContext>(我现在没有它,所以我无法验证确切的名称)在每次我的模型更改时重新初始化我的开发数据库。这发生在Global.asax

但是,我不希望这种情况发生在其他人正在输入真实数据的虚拟主机上。我需要自己处理那里的所有数据库迁移,以便保留数据。

我曾考虑使用#ifdef DEBUG 标记来防止调用数据库初始化程序,但我不喜欢这种解决方案。现在,我已经部署了调试版本,所以如果他们遇到任何错误,我很容易看到并调试它们(这是非常非常 alpha,所以只有少数人在使用它并且知道会出现错误)。

我还有哪些其他选项可以防止 Prod DB 首先被 EF4 代码删除?

【问题讨论】:

    标签: c# database entity-framework deployment entity-framework-4.1


    【解决方案1】:

    控制反转呢:

    var initializer = container.Resolve<IDatabaseInitializer<Context>>();
    Database.SetInitializer(initializer);
    

    根据您的 IoC 配置,您将返回开发或生产初始化程序。您可以为每个构建配置使用不同的配置文件,因此您也可以对 IoC 容器进行不同的配置。

    public class ThrowExceptionInitializer : IDatabaseInitializer<Context>
    {
        public InitializeDatabase(Context context)
        {
            // Custom exception
            throw new InvalidVersionException("The new application version is not supported by the database version");
        }
    }
    

    【讨论】:

      【解决方案2】:

      正如@Johann 所说,ConditionalAttribute 可能是这里的清洁解决方案:

      [Conditional("DEBUG")]
      private void InitializeDb()
      {
          // Initializer code here
          // DropCreateDatabaseOnModelChange<TContext>
      }
      

      在 Global.asax 中:

      public void Application_Start // or wherever it is you're initializing
      {
          // This will only be called if the DEBUG constant is defined
          InitializeDb();
      }
      

      【讨论】:

        【解决方案3】:

        您始终可以创建新配置(除调试和发布之外)。然后,您将为新配置定义一个条件编译符号。例如,如果我创建了一个名为 LocalDebug 的新配置(在默认调试中具有相同的设置),那么我会将 LOCALDEBUG 添加到条件编译符号中。有了这个定义,您可以使用:

        #if LOCALDEBUG
          //do database stuff
        #endif
        

        然后你仍然可以部署内置的调试配置,这部分不会触发。

        【讨论】:

        • 我认为我最喜欢这种方法。谢谢!
        【解决方案4】:

        您可以使用 Conditional 属性,但它与 #ifdef 没有太大区别

        【讨论】:

          【解决方案5】:

          如果您在开发中使用 sql express 而不是在生产环境中,您可以按连接进行过滤。

          protected void Application_Start(object sender, EventArgs e)
          {
            using (var db = new MyDb())
            {
              if (db.Database.Connection.DataSource.IndexOf("sqlexpress", StringComparison.InvariantCultureIgnoreCase) > -1)
              {
                  Database.SetInitializer(new MyDbInitializer());
              }
            }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-07-30
            • 2016-10-19
            • 2019-04-28
            • 2020-11-20
            • 2021-07-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多