【问题标题】:Disable automatic migrations in entity framework在实体框架中禁用自动迁移
【发布时间】:2018-11-13 17:49:07
【问题描述】:

我有这样的 Configuration 类构造函数:

public Configuration() => AutomaticMigrationsEnabled = false;

我什至将我的 DbContent 更新为:

public DatabaseContext()
    : base("DefaultConnection")
{
    Database.CommandTimeout = 900;
    Database.Log = s => Debug.WriteLine(s);
    Configuration.LazyLoadingEnabled = false;
    Database.SetInitializer(new CreateDatabaseIfNotExists<DatabaseContext>());
}

但是当我尝试为特定迁移运行 update-database 时:

update-database -TargetMigration CreateOrganisation

我明白了:

应用显式迁移:[201805081508118_CreateOrganisation]。

应用显式迁移:201805081508118_CreateOrganisation。

应用自动迁移:201805081508117_CreateOrganisation_AutomaticMigration。

它运行的最后一个,然后失败,因为它指出:

System.Data.SqlClient.SqlException (0x80131904):数据库中已经有一个名为“Answers”的对象。

有,但实际迁移看起来像这样:

public partial class CreateOrganisation : DbMigration
{
    public override void Up()
    {
        CreateTable(
                "dbo.Organisations",
                c => new
                {
                    Id = c.String(nullable: false, maxLength: 100),
                    Name = c.String(nullable: false, maxLength: 100),
                    Description = c.String(maxLength: 255),
                })
            .PrimaryKey(t => t.Id);

        AddColumn("dbo.Users", "OrganisationId", c => c.String(maxLength: 100));
    }

    public override void Down()
    {
        DropTable("dbo.Organisations");
        DropColumn("dbo.Users", "OrganisationId");
    }
}

如您所见,在该迁移中没有提及 Answer,这让我认为它正在尝试进行之前的迁移......

有谁知道我该如何阻止它?


protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Table renames
    modelBuilder.Entity<Criteria>().ToTable("Criteria");
    modelBuilder.Entity<Formula>().ToTable("Formulas");
    modelBuilder.Entity<IdentityRole>().ToTable("Roles");
    modelBuilder.Entity<IdentityUserRole>().ToTable("UserRoles");
    modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaims");
    modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogins");
    modelBuilder.Entity<ImageText>().ToTable("ImageText");

    // One to Many  
    modelBuilder.Entity<Criteria>().HasMany(m => m.Attributes).WithOptional().HasForeignKey(m => m.CriteriaId);
    modelBuilder.Entity<IdentityRole>().HasMany(m => m.Users).WithRequired().HasForeignKey(m => m.RoleId);
    modelBuilder.Entity<Organisation>().HasMany(m => m.Feeds).WithRequired().HasForeignKey(m => m.OrganisationId);
    modelBuilder.Entity<Organisation>().HasMany(m => m.Users).WithRequired().HasForeignKey(m => m.OrganisationId);
    modelBuilder.Entity<Group>().HasMany(m => m.Questions).WithOptional().HasForeignKey(m => m.GroupId);
    modelBuilder.Entity<Question>().HasMany(m => m.Answers).WithOptional().HasForeignKey(m => m.QuestionId);

    modelBuilder.Entity<Category>().HasMany(m => m.PriorityColours).WithRequired().HasForeignKey(m => m.CategoryId);
    modelBuilder.Entity<Category>().HasMany(m => m.Criteria).WithRequired().HasForeignKey(m => m.CategoryId);
    modelBuilder.Entity<Category>().HasMany(m => m.Feeds).WithRequired().HasForeignKey(m => m.CategoryId);
    modelBuilder.Entity<Category>().HasMany(m => m.Quotes).WithRequired().HasForeignKey(m => m.CategoryId);
    modelBuilder.Entity<Category>().HasMany(m => m.QuestionGroups).WithRequired().HasForeignKey(m => m.CategoryId);

    modelBuilder.Entity<User>().HasMany(m => m.Searches).WithRequired().HasForeignKey(m => m.UserId);
    modelBuilder.Entity<User>().HasMany(m => m.Charges).WithRequired().HasForeignKey(m => m.UserId);
    modelBuilder.Entity<Answer>().HasMany(m => m.Images).WithRequired().HasForeignKey(m => m.AnswerId);
    modelBuilder.Entity<Image>().HasMany(m => m.ImageText).WithRequired().HasForeignKey(m => m.ImageId);

    // Create our primary keys
    modelBuilder.Entity<IdentityUserLogin>().HasKey(m => m.UserId);
    modelBuilder.Entity<IdentityRole>().HasKey(m => m.Id);
    modelBuilder.Entity<IdentityUserRole>().HasKey(m => new {m.RoleId, m.UserId});
}

根据要求

【问题讨论】:

  • 这些答案都不能解决我的问题
  • 我们可以看看你的 OnModelCreating 是什么样子的吗?
  • 你提到的“重复”不起作用,因为当我尝试创建新的迁移时,它告诉我我还有一些未完成的。我想一一提交,因为他们有一个还不存在的外键。所以我创建了单独的迁移,这样我就可以在添加可空字段之后填充数据,然后再将其转换为外键。
  • 你可以试试-verbose开关看看到底发生了什么。

标签: c# entity-framework


【解决方案1】:

看来你遇到了和我一样的问题,我在下面的链接中找到了答案,它对我有用,希望它也对你有用:

Update-Database tries to do an automatic migration even with automatic migrations disabled

我复制到这里的答案的基本部分:

实体框架将始终在运行显式迁移之前运行自动迁移,该迁移在其 .resx 文件中定义了 Source 属性,即使 AutomaticMigrationsEnabled = false。如果显式迁移是在运行自动迁移之后创建的,那么它只会设置 Source 属性。

结果是禁用自动迁移仅意味着 EF 在检测到模型更改时不会自动升级您的架构 - 但如果它需要填补某些显式迁移之间的空白,它可能仍会执行自动迁移。为避免这种行为,请勿混合使用自动迁移和显式迁移。

流动的步骤是我为解决这个问题所做的:

  • 找到丢失的迁移文件的 resx 文件
  • 打开它并删除源属性。最好能复制这个 resx 文件。
  • 再次运行命令update-database -verbose
  • 挂起的迁移将添加到 _migrationHistory 表中。

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
  • 感谢您的建议,因为我是新手,会更加注意如何回答问题。
猜你喜欢
  • 1970-01-01
  • 2016-07-15
  • 1970-01-01
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多