【问题标题】:Database initialization strategy Code First数据库初始化策略 Code First
【发布时间】:2013-05-08 16:26:18
【问题描述】:

我有一个ASP.NET-MVC 应用程序启用了Migration 并配置了SimpleMemberShipProvider 以使用我的数据库和一些额外的表/字段。

我的问题是,我的数据库初始化放在哪里?因为我仍在开发它,所以我可以删除数据库/表和数据并重新创建它。

我已将它放在 configuration.cs 文件中,但我不确定这是否是数据库初始化程序的位置。

namespace CFContext.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using WebMatrix.WebData;
    using System.Web.Security;
    using System.Collections.Generic;

internal sealed class Configuration : DbMigrationsConfiguration<DataContext>
{
    public Configuration()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<DataContext>());
        //Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DataContext>());
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
    }

    protected override void Seed(DataContext context)
    {
        //  This method will be called after migrating to the latest version.

        //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
        //  to avoid creating duplicate seed data. E.g.
        //
        //    context.People.AddOrUpdate(
        //      p => p.FullName,
        //      new Person { FullName = "Andrew Peters" },
        //      new Person { FullName = "Brice Lambson" },
        //      new Person { FullName = "Rowan Miller" }
        //    );
        //

        SeedMembership(context);
    }

    private void SeedMembership(DataContext context)
    {
        WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

        var roles = (SimpleRoleProvider)Roles.Provider;
        var membership = (SimpleMembershipProvider)System.Web.Security.Membership.Provider;

        if (!roles.RoleExists("Administrator"))
            roles.CreateRole("Administrator");

        if (membership.GetUser("Username0", false) == null)
        {

        }
      }
    }
}

【问题讨论】:

    标签: database asp.net-mvc-4 ef-code-first


    【解决方案1】:

    我把它放在 Global.asax.cs 的 Application_Start 里面

    protected void Application_Start()
            {
                WebSecurity.InitializeDatabaseConnection("Name of Connection String", "User Table in DataBase", "UserId Column", "UserName Column", true);
            }
    

    true,表示我要自动创建表。

    在 Web.config 文件中,您需要设置提供程序:

    <system.web>
        <compilation debug="true" targetFramework="4.6.1" />
        <httpRuntime targetFramework="4.6.1" />
    
        <membership defaultProvider="nameProvider">
          <providers>
            <add name="nameProvider" type="WebMatrix.WebData.SimpleMembershipProvider,WebMatrix.WebData" />
          </providers>
        </membership>
      </system.web>
    

    它对我有用。

    【讨论】:

      【解决方案2】:
      public class ContextInitializer : CreateDatabaseIfNotExists<Context>
      {     
          private static void InitializeWebSecurity()
          {
              if (WebSecurity.Initialized)
                  return;
      
              WebSecurity.InitializeDatabaseConnection(
                  connectionStringName: "DefaultConnection",
                  userTableName: "User",
                  userIdColumn: "Id",
                  userNameColumn: "Email",
                  autoCreateTables: true);
      
              Roles.CreateRole("Admin");
              Roles.CreateRole("Customer");
          }       
      
          protected override void Seed(Context context)
          {
              InitializeWebSecurity();
      
              // more seeding
              context.SaveChanges();
          }
      }
      
      public class MvcApplication : System.Web.HttpApplication
      {
          protected void Application_Start()
          {
              AreaRegistration.RegisterAllAreas();
              WebApiConfig.Register(GlobalConfiguration.Configuration);
              FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
              RouteConfig.RegisterRoutes(RouteTable.Routes);
              BundleConfig.RegisterBundles(BundleTable.Bundles);
              AuthConfig.RegisterAuth();
              DatabaseConfig.RegisterDatabase();
              AutoMapperConfig.RegisterConfig();
      
              // Set the initializer here
              Database.SetInitializer(new ContextInitializer());
      
              // Now initialize it
              using (var context = new Context())
              {
                  context.Database.Initialize(false);
              }
      
              // Double check seeding has initalized, if not
              // We initialize it here to make sure.
              if (!WebSecurity.Initialized)
              {
                  WebSecurity.InitializeDatabaseConnection(
                      connectionStringName: "DefaultConnection", 
                      userTableName: "User", 
                      userIdColumn: "Id", 
                      userNameColumn: "Email", 
                      autoCreateTables: false);
              }
          }
      }
      

      您应该能够使用此设置以相同的方式创建迁移。

      【讨论】:

      • 嗨,这里令人困惑的部分是,如果您启用迁移,则 configuration.cs 文件已经有一个受保护的覆盖 void Seed(Context context) 方法。可以在多个地方使用它吗?
      • 你应该只设置一个初始化策略,所以 CreateDatabaseIfNotExists 不应该在你的。只需确保您设置了初始化策略以使用您的迁移设置。拥有两种不同的类型应该不会影响它。
      • 我的意思是 Seed() 方法,当启用迁移时,它也在 configuration.cs 中。我会有两次 Seed() 方法。
      • 但是种子方法只能由 Configuration.cs 调用,因为这是您选择的初始化策略。如果您选择 CreateDatabaseIfNotExists,则会调用该种子函数。
      • 那么两次使用 Seed() 方法就可以了吗?我已经用 configuration.cs 的内容更新了我的问题
      【解决方案3】:

      将您的数据库初始化代码放入 Global.asax

      上的“Application_Start”方法中

      【讨论】:

      • 嗨,如果我在 NuGet 控制台中执行“更新数据库”命令会发生什么?它也会出现在 Global.asax 中吗?
      • 它应该知道一旦你编译了程序集,需要发生什么。
      • 我在类库中启用了迁移。我将数据库操作从 Web 项目中分离出来。
      • 我也是这样。然后我在我的 MVC 项目中引用我的“数据库”项目。
      猜你喜欢
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 2015-08-07
      • 1970-01-01
      相关资源
      最近更新 更多