升级 EF5.x 到 EF6.1.3,奇怪的迁移变化

Upgraded EF5.x to EF6.1.3, strange migration changes

我有一个升级到 EF6.1.3 的现有 EF5 项目。如果我在 EF5 上执行 "Add-Migration",我会按预期进行空迁移,但在我升级到 EF6 和 "add-migration" 之后,我会得到一堆 st运行ge 更改。唯一一致的是,有一个多对多 table 以前从未在 EF/migrations 中定义过,它似乎是过去的开发人员手动创建的,现在看起来好像找到了 EF6它并决定通过尝试重命名 table 来承认它,我不知道为什么。这是它想要执行的 st运行ge 更改

RenameTable(name: "dbo.DashboardUserDashboards", newName: "DashboardDashboardUsers");
RenameTable(name: "dbo.DashboardOrganizationAdjunctDashboardProcesses", newName: "DashboardProcessDashboardOrganizationAdjuncts");
RenameColumn(table: "dbo.DashboardProcessTaskTriggers", name: "DaysOfWeek", newName: "__mig_tmp__0");
RenameColumn(table: "dbo.DashboardProcessTaskTriggers", name: "DaysOfWeek1", newName: "DaysOfWeek");
RenameColumn(table: "dbo.DashboardProcessTaskTriggers", name: "__mig_tmp__0", newName: "DaysOfWeek1");

我从来没有 运行 这些,代码库 运行 很好,我添加了一个新的迁移,它是空的,我在其中添加了一个不相关的存储过程,它也 运行 很好&代码执行。但是现在当我 运行 代码库时,我得到了异常

Invalid object name 'dbo.DashboardDashboardUsers'.
Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.DashboardDashboardUsers'.

我搜索了整个解决方案,代码库中的任何地方都没有引用那个坏的 table name/object,也没有更改数据库(因为我注释掉了代码)。我该如何解决这个错误,因为某些东西是硬编码的,但它不在任何 .cs 文件中的任何地方?出于绝望,我什至将重命名添加到我的迁移中,然后在它之后将其重命名回来,但这仍然会出现错误。修复异常的唯一方法是让重命名执行,我绝对不希望这样做,因为它打破了我们的命名约定,而且这个代码库已经投入生产多年,它不是 acceptable 更改。

您的问题似乎是由于 EF6 在代码中未明确定义配置时应用了与 EF5 不同的约定。因此,您可以尝试明确定义这些配置。您可以在 DbContext class.

中的 OnModelCreating 方法中执行此操作
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    ...
    <your configurations here>
}

我能想到一些可以尝试的事情:

  • 明确设置架构:

    modelBuilder.HasDefaultSchema("dbo");
    

    您的架构名称似乎是 dbo。请注意,在您的 RenameTable 句子中,table 名称不同,但旧名称也包含模式前缀,但新名称不包含。

  • 配置多对多关系的映射:

    modelBuilder.Entity<User>()
        .HasMany(x => x.Dashboards)
        .WithMany(x => x.Users)
        .Map(x => { 
            x.MapRightKey("UserId"); 
            x.MapLeftKey("DashboardId"); 
            x.ToTable("DashboardUserDashboards"); 
         } );
    

    这里的关键部分是 .ToTable("DashboardUserDashboards") 明确设置 table 物理名称的配置。对于其他配置,我对您的模型 classes 做了一些假设,因为您没有显示该代码,例如您具有导航属性 User.DashboardsDashboard.Users。也许您没有这些导航属性,因为您不需要它们。您必须使该代码适应您的特定模型 classes.

如果您有很多 EF 配置代码,最好为每个实体使用映射 class,使用您的模型类型参数扩展 EntityTypeConfiguration class class:

public class UserMap : EntityTypeConfiguration<User>
{
    public Map()
    {
        HasMany(x => x.Dashboards)
             ...
    }
}

这是一个典型的OnModelCreating方法:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.HasDefaultSchema("auth");
    var assembly = Assembly.GetExecutingAssembly();
    modelBuilder.Configurations.AddFromAssembly(assembly);
    modelBuilder.Conventions.AddFromAssembly(assembly);
}

通过使用 Configurations.LoadFromAssembly,您可以应用在 EntityTypeConfiguration classes 中定义的所有配置。您还可以定义一些明确的约定并将它们应用到 Conventions.LoadFromAssembly.

EF6 映射和约定非常强大。在 msdn 中,您可以找到有关 configurations and conventions.

的详细信息