EF Core迁移报错求助:WPF项目重构后上下文移至类库
EF Core迁移失败问题排查与解决
问题背景
重构旧WPF项目时,将泛型DbContext移至类库,执行Add-Migration命令时报错。相关代码如下:
泛型DbContext与工厂类(类库项目)
namespace WPFDemoApp.Common.Context { public class ApplicationDbContext<TEntity> : DbContext where TEntity : class { public ApplicationDbContext(DbContextOptions<ApplicationDbContext<TEntity>> options) : base(options) { } public DbSet<TEntity> Entities { get; set; } } public class ApplicationDbContextFactory<TEntity> : IDesignTimeDbContextFactory<ApplicationDbContext<TEntity>> where TEntity : class { public ApplicationDbContext<TEntity> CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext<TEntity>>(); optionsBuilder.UseSqlite("Data Source=localdatabase.db"); return new ApplicationDbContext<TEntity>(optionsBuilder.Options); } } }
WPF项目中的服务注册
namespace WPFDemoApp { public static class ServiceRegistration { public static IServiceProvider ConfigureServices() { var services = new ServiceCollection(); services.AddDbContext<ApplicationDbContext<ToDoItem>>( options => options.UseSqlite("Data Source=localdatabase.db")); services.AddScoped<MainWindow>(); services.AddScoped<ToDoItem>(); services.AddScoped<IRepository<ToDoItem>, Repository<ToDoItem>>(); services.AddScoped<IGetAllDataUseCase<ToDoItem>, GetAllDataUseCase<ToDoItem>>(); services.AddScoped<MainViewModel<ToDoItem>>(); return services.BuildServiceProvider(); } } }
问题原因
EF Core迁移工具无法处理泛型DbContext和泛型IDesignTimeDbContextFactory:
- 迁移工具需要明确的、非泛型的上下文类型来扫描实体元数据、生成迁移代码,泛型类型无法提供明确的扫描目标
- 泛型工厂类无法被工具自动识别,工具无法确定要实例化的具体上下文实现
解决步骤
1. 创建非泛型的具体DbContext子类
在类库项目中,基于泛型上下文创建对应实体的具体上下文:
namespace WPFDemoApp.Common.Context { public class ToDoItemDbContext : ApplicationDbContext<ToDoItem> { public ToDoItemDbContext(DbContextOptions<ToDoItemDbContext> options) : base(options) { } } }
2. 创建对应非泛型的设计时工厂
同样在类库项目中,实现针对具体上下文的IDesignTimeDbContextFactory:
namespace WPFDemoApp.Common.Context { public class ToDoItemDbContextFactory : IDesignTimeDbContextFactory<ToDoItemDbContext> { public ToDoItemDbContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder<ToDoItemDbContext>(); optionsBuilder.UseSqlite("Data Source=localdatabase.db"); return new ToDoItemDbContext(optionsBuilder.Options); } } }
3. 更新WPF项目的服务注册
将原来的泛型上下文注册替换为具体上下文:
services.AddDbContext<ToDoItemDbContext>( options => options.UseSqlite("Data Source=localdatabase.db"));
4. 执行迁移命令
在Package Manager Console中执行迁移命令,指定具体上下文和项目(如果类库是单独项目):
Add-Migration InitialCreate -Context ToDoItemDbContext -Project WPFDemoApp.Common -StartupProject WPFDemoApp
内容的提问来源于stack exchange,提问作者Mariusz
相关产品推荐
相关产品推荐

