升级 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.Dashboards
和 Dashboard.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.
的详细信息
我有一个升级到 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.Dashboards
和Dashboard.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.
的详细信息