EF Core同库多DbContext间导航属性及迁移问题咨询
我帮你梳理下这个场景下的核心解决方案,毕竟单库多DbContext的迁移确实容易踩坑:
给每个DbContext配置独立的迁移历史表
默认情况下,EF Core所有DbContext都会共用__EFMigrationsHistory表记录迁移,这会导致两个上下文的迁移记录互相干扰。你需要在每个DbContext的OnConfiguring方法里指定专属历史表:protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer( "你的数据库连接字符串", x => x.MigrationsHistoryTable("__EFMigrationsHistory_FirstContext")); }第二个DbContext就换成比如
__EFMigrationsHistory_SecondContext,这样各自的迁移轨迹就不会打架了。生成迁移时必须明确指定DbContext
不管用Package Manager Console还是.NET CLI,生成迁移时一定要指定对应的上下文,不然EF Core不知道该处理哪个:- PM命令:
Add-Migration InitialCreate -Context FirstDbContext - CLI命令:
dotnet ef migrations add InitialCreate --context FirstDbContext
给第二个DbContext生成迁移时,把FirstDbContext换成第二个上下文的类名即可。
- PM命令:
更新数据库时也要对应指定DbContext
执行迁移更新数据库时,同样要匹配上下文:- PM命令:
Update-Database -Context FirstDbContext - CLI命令:
dotnet ef database update --context FirstDbContext
两个上下文的迁移要分别执行,确保各自负责的表结构都能正确生成。
- PM命令:
处理跨上下文的重复实体(比如你的User实体)
如果第二个DbContext也需要访问User实体,一定要确保它映射到和第一个上下文相同的表,避免生成重复表。可以在第二个DbContext的OnModelCreating里配置:protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>().ToTable("Users"); // 和第一个上下文的表名保持完全一致 }另外两个上下文里的User实体字段最好保持一致,不然可能引发结构冲突。如果第二个上下文不需要修改User表结构,也可以用
modelBuilder.Ignore<User>()直接忽略该实体,只处理自己负责的部分。防止迁移误包含其他上下文的实体
有时候EF Core会不小心把其他上下文的实体纳入当前迁移,这时候要检查DbContext的DbSet定义,确保只包含当前上下文负责的实体;必要时在OnModelCreating里显式忽略不属于当前上下文的实体。
内容的提问来源于stack exchange,提问作者SzilardD

