Azure持续部署-代码优先迁移种子问题(MVC 5)

3
我已经在Microsoft Azure(Web App)中使用ButBucket Git存储库设置了“持续部署”。我在电脑上成功地运行了Code First Migrations,它创建了表并插入了数据。但当我同步分支时,“迁移的Seed方法在Azure上没有运行”。
因此,Azure从BitBucket获取更改,根据需要创建表,但不运行种子方法(每个表都保持为空)。
您能否建议一种解决方案,在应用新的迁移时自动在Azure上运行Seed方法(或者如果那是唯一的解决方案,那么在Azure从BitBucket构建后每次运行)?
附加信息:
- MigrationHistory表包含迁移,因此它们已经运行过。 - 我已将AutomaticMigrationsEnabled = true;但问题仍然存在。 - 在Azure上有一个Web App可以进行构建和迁移,以及一个SQL数据库,该数据库在Web.config中的ConnectionString中被引用。
Configuration.cs
internal sealed class Configuration : DbMigrationsConfiguration<MyInsidR.Models.ApplicationDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        ContextKey = "MyInsidR.Models.ApplicationDbContext";
    }

    protected override void Seed(ApplicationDbContext 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" }
        //    );
        //

        context.Prophecies.AddOrUpdate(p => p.ID,
            new Prophecy() { ID = 1, Text = "Fűben iszogatós, sírva nevetős."}
        );

        context.Interesteds.AddOrUpdate(x => x.ID,
            new Interested() { ID = 1, Email = "teszt.elek@gmail.com", FirstName = "Elek", LastName = "Teszt", RegistrationDate = DateTime.Now }
        );

        var tag1 = new Tag() { ID = 1, Name = "Karaoke", ApplyTo = TagApplication.All, Type = TagType.Games };
        var tag3 = new Tag() { ID = 3, Name = "4 rooms", ApplyTo = TagApplication.All, Type = TagType.Misc };
        var tag4 = new Tag() { ID = 4, Name = "Helipad", ApplyTo = TagApplication.All, Type = TagType.Vip };

        context.Tags.AddOrUpdate(x => x.ID,
            tag1, tag3, tag4
        );

        var indicatorIcon1 = new IndicatorIcon() { ID = 1, VisualClass = IndicatorIcon.VisualClassType.Hidden, Name = "No Indicator Icon", Description = "Nothing special, just a regular place or event." };
        var indicatorIcon2 = new IndicatorIcon() { ID = 2, VisualClass = IndicatorIcon.VisualClassType.Fire, Name = "Hot", Description = "This place or event is very popular at the moment. There are big parties and a big fuss around it." };
        context.IndicatorIcons.AddOrUpdate(x => x.ID,
            indicatorIcon1, indicatorIcon2
        );

        AddUserAndRole(context);
    }

    bool AddUserAndRole(ApplicationDbContext context)
    {
        var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
        var identityResult = roleManager.Create(new IdentityRole("Admin"));

        var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
        var user = new ApplicationUser()
        {
            UserName = "myinsidr@gmail.com",
        };
        identityResult = userManager.Create(user, "Qwertz1234!");
        if (identityResult.Succeeded == false)
            return identityResult.Succeeded;

        identityResult = userManager.AddToRole(user.Id, "Admin");
        return identityResult.Succeeded;
    }
}

我发现与种子方法问题相关的问题和解决方案仅适用于从Visual Studio直接部署,但这不是我想要的方式。
此外,虽然有使用不同SQL管理项目的解决方案,但如果像在我的本地机器上一样工作,则MVC项目中的代码优先迁移是最清洁的解决方案。

你解决了这个问题吗? - erwineberhard
是的,但我不得不修改代码而不是之前的概念,以在Azure UI或某个配置文件中修复它。请查看我的答案以获取详细信息! - Ádám Miklósi
1个回答

2
我已经找到了如何使用这种技术在每次服务器启动时运行种子方法的方法:http://romiller.com/2012/02/09/running-scripting-migrations-from-code/ 对我来说,在每次Azure持续部署构建后运行种子非常好。当然,它也会在其他情况下运行,但我的方法不太长,所以无关紧要。
我将以下代码放在Global.asax-->Application_Start()中:
var migrator = new DbMigrator(new Configuration());
migrator.Update();

As

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    // CODE FIRST MIGRATIONS
    #if !DEBUG
       var migrator = new DbMigrator(new Configuration());
       migrator.Update();
    #endif
}

这个功能实际上是在每次服务器启动时运行一个Code First Migration。

是的,那就是解决方案。 - erwineberhard
当我尝试这个解决方案时,在部署后我遇到了以下异常:数据库中已经存在一个名为'PuzzleHunts'的对象。异常详细信息:System.Data.SqlClient.SqlException: 数据库中已经存在一个名为'PuzzleHunts'的对象。我猜测它正在尝试创建已经存在的表。我希望保留现有的表并且在不重新创建它们的情况下"升级"模式。对于如何在持续部署中实现这一点,您有什么建议吗? - DanJosef
以上解决方案只会自动运行迁移。结果将与您在包管理器控制台中使用Update-Database运行迁移完全相同。 https://msdn.microsoft.com/en-us/data/dn579398.aspx您遇到的问题是由于错误的迁移文件。打开您的迁移文件夹并修订您的.cs迁移文件,因为某处应该有一个额外的CreateTable(...)方法。 也许您已经在开发计算机上生成了迁移文件(使用Add-Migration),而该计算机的数据库与您的服务器相反不包含表。 - Ádám Miklósi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接