EF Code First双上下文共享实体类:单上下文实体属性修改需求咨询
解决EF Code First多上下文共享实体但差异化字段的问题
这个场景我之前做项目的时候碰到过,核心就是要在共享实体类的前提下,让不同的DbContext对实体的映射规则差异化处理。这里有两个实用的方案,你可以根据自己的代码洁癖程度来选:
方案一:派生实体类+同表映射(推荐,代码隔离更干净)
如果不想让不需要新增字段的上下文看到额外属性,这个方案能保持各上下文的实体类更纯净。
- 第一步:保留原有的共享实体类(这是两个上下文共用的基础属性)
public class Person { public int Id { get; set; } public string Name { get; set; } // 其他原有共用属性... } public class Grade { public int Id { get; set; } public string Name { get; set; } // 原有共用属性... }
- 第二步:为需要新增字段的上下文创建派生实体
// 只在需要新增字段的上下文里使用这个派生类 public class PersonWithAge : Person { public int Age { get; set; } // 新增的专属字段 }
- 第三步:修改目标上下文的接口和实现,替换为派生类并配置映射
// 修改你的接口定义 public interface IPeopleFirstGroupDbContxt { IDbSet<PersonWithAge> Person { get; set; } IDbSet<Grade> Grades { get; set; } // 其他DbSet... } // 上下文实现类 public class PeopleFirstGroupDbContext : DbContext, IPeopleFirstGroupDbContxt { public IDbSet<PersonWithAge> Person { get; set; } public IDbSet<Grade> Grades { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 把派生类映射到原有的Person表,确保数据互通 modelBuilder.Entity<PersonWithAge>().ToTable("Person"); // 其他原有配置... } }
- 第四步:另一个上下文完全不用改,继续使用原
Person类,它会自动忽略派生类的新增字段,只映射原有属性到Person表。
方案二:共享实体类+Fluent API忽略字段(更直接,适合快速修改)
如果不想新增派生类,只想在原实体里加字段,然后让不需要的上下文忽略它,这个方案更省代码。
- 第一步:在原共享实体类里新增字段
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } // 新增的字段 // 其他原有共用属性... }
- 第二步:在不需要这个字段的DbContext里配置忽略
public class SecondDbContext : DbContext { public IDbSet<Person> Person { get; set; } public IDbSet<Grade> Grades { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 告诉EF在这个上下文里忽略Age字段,不会映射到数据库 modelBuilder.Entity<Person>().Ignore(p => p.Age); // 其他原有配置... } }
- 第三步:需要新增字段的上下文(比如
PeopleFirstGroupDbContext)不用做任何额外配置,EF会自动把Age字段映射到数据库表的对应列。
注意事项
- 迁移操作要注意:使用方案一的时候,只有包含派生类的上下文会生成新增字段的迁移脚本;方案二里,只有未配置忽略的上下文会处理新增字段。
- 方案二中,不需要新增字段的上下文里,
Person类的Age属性只是内存属性,EF不会把它和数据库关联,读取时会是默认值,写入也不会保存到数据库,业务代码里要注意这一点。
内容的提问来源于stack exchange,提问作者PowerPuffGirl
相关产品推荐
相关产品推荐

