如何在数据库迁移中使用Person子类且不映射基类Person?
实现方案:抽象基类+继承特性,不将基类映射到数据库
核心思路
要达成你的需求,关键是把Person设为抽象基类,不在DbContext中注册它的DbSet,同时在基类属性上添加EF Core数据注解特性——这些特性会被子类继承,迁移时自动应用到子类对应的数据库列上。
具体步骤与代码示例
1. 修改Person为抽象类并添加特性
把Person改为抽象类,在需要的属性上添加EF Core数据注解(比如主键、必填、列类型等),这些特性会被子类继承:
public abstract class Person { [Key] // 主键特性,子类继承后Id会作为各自表的主键 public int Id { get; set; } [Required] [Column(TypeName = "nvarchar(50)")] public string FirstName { get; set; } [Required] [Column(TypeName = "nvarchar(50)")] public string LastName { get; set; } [Range(0, 120)] public int Age { get; set; } }
2. 定义子类
创建继承自Person的子类,添加各自独有的属性即可:
public class Employee : Person { // 子类独有属性 public string EmployeeCode { get; set; } } public class Customer : Person { // 子类独有属性 public string CustomerNumber { get; set; } }
3. 配置DbContext
只在DbContext中注册子类的DbSet,不要注册Person的DbSet,这样EF Core不会把Person当作独立实体:
public class AppDbContext : DbContext { // 仅注册子类的DbSet public DbSet<Employee> Employees { get; set; } public DbSet<Customer> Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("你的数据库连接字符串"); } }
4. 选择继承映射策略
根据你的数据库设计需求,选择合适的EF Core继承映射策略:
- TPCC(每个具体类一张表):最符合你“不添加Person类到数据库”的需求。每个子类会生成独立的表,包含Person的所有属性和自己的独有属性,数据库中没有Person对应的表。EF Core默认会在基类为抽象且无DbSet时自动采用这种策略,无需额外配置。
- TPH(每个层次结构一张表):所有子类和基类的属性会合并到一张表中,通过
Discriminator列区分不同子类。如果需要这种策略,无需额外配置,EF Core默认启用。 - TPT(每个类型一张表):基类和子类各对应一张表,子类表通过外键关联基类表。但这种策略会生成Person对应的表,不符合你的需求,不推荐使用。
验证与迁移
完成配置后,运行EF Core迁移命令:
Add-Migration InitialCreate Update-Database
迁移生成的数据库中只会包含Employees和Customers表(TPCC策略下),且两张表都会包含Person类中带特性的属性,特性规则会被正确应用。
内容的提问来源于stack exchange,提问作者Keruxxa
相关产品推荐
相关产品推荐

