EF6启动时抛出‘Invalid object name 'dbo.__MigrationHistory'’异常求助
问题分析与解决思路
异常原因
EF6默认会在上下文初始化时检查迁移历史表__MigrationHistory,即使你为每个上下文指定了自定义Schema,若存在以下情况,仍会触发对dbo.__MigrationHistory的访问:
- 某个上下文未正确关联自定义HistoryContext,EF回退到默认行为
- 迁移初始化器配置错误,绑定了默认的迁移逻辑
- DI容器中存在未正确配置的上下文实例
- 第三方代码或初始化逻辑意外创建了默认配置的DbContext
解决步骤
1. 为每个自定义Schema上下文创建专属HistoryContext
针对data、results、web三个Schema,分别创建对应的HistoryContext,明确指定迁移表的Schema:
// Data Schema对应的HistoryContext public class DataHistoryContext : HistoryContext { public DataHistoryContext(DbConnection connection, string defaultSchema) : base(connection, defaultSchema) { DefaultSchema = "data"; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 将迁移表绑定到data Schema modelBuilder.Entity<HistoryRow>().ToTable("__MigrationHistory", "data"); } } // Results Schema对应的HistoryContext public class ResultsHistoryContext : HistoryContext { public ResultsHistoryContext(DbConnection connection, string defaultSchema) : base(connection, defaultSchema) { DefaultSchema = "results"; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<HistoryRow>().ToTable("__MigrationHistory", "results"); } } // Web Schema对应的HistoryContext public class WebHistoryContext : HistoryContext { public WebHistoryContext(DbConnection connection, string defaultSchema) : base(connection, defaultSchema) { DefaultSchema = "web"; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<HistoryRow>().ToTable("__MigrationHistory", "web"); } }
2. 在每个DbContext中绑定对应的HistoryContext
修改每个上下文的构造函数,指定HistoryContextFactory,确保EF使用自定义的迁移表:
public class DataContext : DbContext { public DataContext(string connectionString) : base(connectionString) { // 绑定DataHistoryContext Configuration.HistoryContextFactory = (connection, schema) => new DataHistoryContext(connection, schema); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 设置默认Schema为data modelBuilder.HasDefaultSchema("data"); // 其他实体配置... } } // 同理配置ResultsContext和WebContext,分别绑定对应的HistoryContext
3. 检查并修正迁移初始化器配置
确保每个上下文的迁移初始化器使用专属的迁移配置,避免默认逻辑:
// Data上下文的迁移配置 internal sealed class DataMigrationsConfig : DbMigrationsConfiguration<DataContext> { public DataMigrationsConfig() { AutomaticMigrationsEnabled = false; // 指定迁移文件存放目录(可选) MigrationsDirectory = @"Migrations\DataMigrations"; TargetDatabase = new DbConnectionInfo("YourConnectionString", "System.Data.SqlClient"); } protected override void Seed(DataContext context) { // 种子数据逻辑... } } // 启动时为DataContext设置初始化器 Database.SetInitializer(new MigrateDatabaseToLatestVersion<DataContext, DataMigrationsConfig>()); // 同样为ResultsContext和WebContext创建对应的迁移配置并设置初始化器
4. 排查DI容器与初始化逻辑
- 确认DI容器中注册的所有DbContext实例均为上述配置好的版本,无默认构造的DbContext
- 检查启动时的初始化代码,避免第三方库或自定义逻辑意外创建未配置的DbContext实例
- 可通过断点调试异常触发的调用栈,定位具体是哪个上下文导致对
dbo.__MigrationHistory的访问
5. 验证迁移表存在
确保每个自定义Schema下已创建对应的__MigrationHistory表,可通过手动执行迁移命令生成:
# 为Data上下文生成迁移 Add-Migration -ConfigurationTypeName DataMigrationsConfig -Name InitialCreate Update-Database -ConfigurationTypeName DataMigrationsConfig # 同理为Results和Web上下文执行迁移命令
内容的提问来源于stack exchange,提问作者Merlin May
相关产品推荐
相关产品推荐

