10 EF Core 继承类关系映射
1、约定情况,可以在模型中包含类型,通过 DbSet 公开继承层次结构中每个类型
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } //约定指定映射表到数据库 public DbSet<RssBlog> RssBlogs { get; set; } //约定指定映射表到数据库 } public class Blog { public int BlogId { get; set; } public string Url { get; set; } } //继承类 public class RssBlog : Blog { public string RssUrl { get; set; } }
Blog、RssBlog 模型在数据库表里以基类的名称映射同一张表,对不同的数据模型类型用Discriminator字段标识,如果想更换Discriminator 字段名为其它名时可以使用Fluent API配置
数据库列会根据数据库模型类型需要自动设置模型中没有类型的字段为null
2、HasBaseType
显式指定基类型
如果不依赖约定在MyContext类型配置public DbSet<Blog> Blogs { get; set; } 属性可以使用 HasBaseType
显式指定基类型
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<RssBlog>().HasBaseType<Blog>(); base.OnModelCreating(modelBuilder); }
3、类型上继承基类,但是希望映射数据库时,不同的类型映射不同的表,使用 HasBaseType((Type)null)
从层次结构中删除实体类型
public class BloggingContext : DbContext { protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<RssBlog>() .HasBaseType((Type)null) //设置没有基类,在数据库中就映射为不同的表 .HasKey(rb => rb.BlogId); //如果继承类中没有定义主键的话,设置基类的主键为继承类的主键, base.OnModelCreating(modelBuilder); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } } //继承类 public class RssBlog : Blog { public string RssUrl { get; set; } }
4、Discriminator列的配置
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasDiscriminator<string>("BlogType") //设置标识列的数据类型string,列名为:BlogType. 数据类型可以是string、int .HasValue<Blog>("Blog_Base") //指定数据库插入一条数据是,不同的数据类型标识不同的值。 插入Blog类型的数据时,BlogType列值为:BlogBase .HasValue<RssBlog>("Blog_RSS");
modelBuilder.Entity<Blog>()
.HasDiscriminator<int>("BlogType") //设置BlogType为int类型
.HasValue<Blog>(0) //插入Blog类型数据时,BlogType对应的值时0
.HasValue<RssBlog>(1)
.HasValue<XmlBlog>(2);
}