实体框架自动重命名多对多表而不进行任何更改

时间:2016-12-01 09:58:17

标签: c# entity-framework ef-code-first ef-migrations

我在同一个项目工作了将近一年半,今天当我想对db(代码优先)添加更改时,所有突然的EF迁移都希望重命名多个多对多表格今天存在于数据库中。 Theese表名称已经超过2年没有变化,我无法弄清楚为什么EF想要重命名它们。 我已经检查了迁移所指向的实体文件,并且没有对可以解释此问题的文件进行更改。 在这个项目中,我们使用数据注释,因此我们从未给多对多表赋予任何名称,我们只是让EF设置表的名称。 任何帮助表示赞赏!

        RenameTable(name: "dbo.FilterLocation", newName: "LocationFilter");
        RenameTable(name: "dbo.FilterCluster", newName: "ClusterFilter");
        RenameTable(name: "dbo.ProfileFilter", newName: "FilterProfile");
        RenameTable(name: "dbo.HtmlTemplateFilterProfile", newName: "ProfileHtmlTemplateFilter");
        RenameTable(name: "dbo.HtmlTemplateProfile", newName: "ProfileHtmlTemplate");
        RenameTable(name: "dbo.CategoryHtmlTemplateFilter", newName: "HtmlTemplateFilterCategory");
        RenameTable(name: "dbo.HtmlTemplateCategory", newName: "CategoryHtmlTemplate");
        DropPrimaryKey("dbo.LocationFilter");
        DropPrimaryKey("dbo.ClusterFilter");
        DropPrimaryKey("dbo.FilterProfile");
        DropPrimaryKey("dbo.ProfileHtmlTemplateFilter");
        DropPrimaryKey("dbo.ProfileHtmlTemplate");
        DropPrimaryKey("dbo.HtmlTemplateFilterCategory");
        DropPrimaryKey("dbo.CategoryHtmlTemplate");
         AddPrimaryKey("dbo.LocationFilter", new[] { "Location_LocationId", "Filter_FilterId" });
        AddPrimaryKey("dbo.ClusterFilter", new[] { "Cluster_ClusterId", "Filter_FilterId" });
        AddPrimaryKey("dbo.FilterProfile", new[] { "Filter_FilterId", "Profile_ProfileId" });
        AddPrimaryKey("dbo.ProfileHtmlTemplateFilter", new[] { "Profile_ProfileId", "HtmlTemplateFilter_HtmlTemplateFilterId" });
        AddPrimaryKey("dbo.ProfileHtmlTemplate", new[] { "Profile_ProfileId", "HtmlTemplate_HtmlTemplateId" });
        AddPrimaryKey("dbo.HtmlTemplateFilterCategory", new[] { "HtmlTemplateFilter_HtmlTemplateFilterId", "Category_CategoryId" });
        AddPrimaryKey("dbo.CategoryHtmlTemplate", new[] { "Category_CategoryId", "HtmlTemplate_HtmlTemplateId" });

*编辑 我实际做的改变如下:

    AddColumn("dbo.HtmlAdField", "MediaFactConnection", c => c.Int(nullable: false));
    AddColumn("dbo.HtmlAd", "FactId", c => c.Int());
    CreateIndex("dbo.HtmlAd", "FactId");
    AddForeignKey("dbo.HtmlAd", "FactId", "dbo.Fact", "FactId");
    DropColumn("dbo.HtmlAdField", "ConnectionState");

1 个答案:

答案 0 :(得分:4)

对于任何绊倒这篇文章的人......

与我最初的评论相反,我的问题并没有通过让迁移按生成运行来解决。我发现了为什么这种行为发生,如何修复它,并从头开始学习了更明确地配置我的实体的课程。

为什么?

实体框架将根据其算法配置实体的顺序命名和配置联结表。 DbSet<>modelBuilder'定义'出现的顺序会更改哪个表左/右用于联结表。我无法确切地确定这对于生成的代码究竟是哪个/如何影响,但在我的情况下,在完全易于攻击的Resharper'代码清理'之后,它都变成了梨形。

如何修复

通过显式配置多对多映射,您可以在首次创建表时模仿EF生成的行为。

这篇文章让我走上正轨: Creating Many To Many Relationships using Fluent API in Entity Framework

就我而言,EF试图将RoleCategory表重命名为CategoryRole(并失败)。这是我做的补充:

modelBuilder.Entity<Role>()
     .HasMany(e => e.Categories)
     .WithMany(e => e.Roles)
         .Map(m =>
         {
             m.ToTable("RoleCategory");
         });

备注

配置'from'在表名中首先命名的实体。例如对于我的表RoleCategory我这样做了:

Entity<Role>.HasMany(e => e.Categories)

Entity<Category>.HasMany(e => e.Roles)

包含一个明确的.WithMany(e => e.Roles),用于在另一侧命名导航属性。

使用.Map()指定表名。在我的情况下,当我使用.MapLeftKey().MapRightKey()指定列名时,链接后的帖子失败。

基本上我只需要继续摆弄定义并每次都运行add-migration,直到对表格的所有操作都从生成的DbMigration文件中消失。

我的课程

显然,最佳做法是从一开始就明确配置所有多对多关系。就我而言,我没有对连接表中涉及的任何实体进行任何更改。然而,对一个遥远的“堂兄”实体的改变以及对DbContext的一些重新排序让我陷入了一段时间的困境。

经验教训。希望其他人也觉得这很有帮助。