EFCore 之 Entity继承

时间:2021-08-06
本文章向大家介绍EFCore 之 Entity继承,主要包括EFCore 之 Entity继承使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

官网示例

https://docs.microsoft.com/zh-cn/ef/core/modeling/inheritance


entity 定义

#region entity for Inherit

    public class Animal
    {
        public int Id { get; set; }

        public string Name { get; set; }
    }

    public class Dog : Animal
    {
        public double Speed { get; set; }
    }

    public class Cattle : Animal
    {
        public double PhysicalStrength { get; set; }
    }

#endregion entity for Inherit


DbContext 实现类

说明

  • 输出日志到控制台
  • 使用鉴别器(HasDiscriminator)配置所有继承类以及父类,并初始化
  • migration时会在table中添加这个鉴别器字段(animal_type)
 public class DataDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseNpgsql("Server=localhost;Port=5432;Database=npgsql_demo;UID=postgres;PWD=********").LogTo(Console.WriteLine);
            base.OnConfiguring(optionsBuilder);
        }

        public DbSet<Animal> Animals { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Animal>()
                        .HasDiscriminator<int>("animal_type")
                        .HasValue<Animal>(0)
                        .HasValue<Dog>(1)
                        .HasValue<Cattle>(2);

            base.OnModelCreating(modelBuilder);
        }
    }


初始化数据

private void Init()
{
   if (!context.Animals.Any())
   {
       context.Animals.Add(new Dog
       {
           Id = 1,
           Name = "拉布拉多",
           Speed = 70
       });

       context.Animals.Add(new Cattle
       {
           Id = 2,
           Name = "荷斯坦牛",
           PhysicalStrength = 500
       });

       context.Animals.Add(new Animal
       {
           Id = 3,
           Name = "外星人"
       });

       context.SaveChanges();
  }
}

分类查询

说明

  • pgsql 区分大小写 使用 "" 包裹
  • 日志那个颜色是截图时win带的荧光笔
protected override void Action()
{
    var animals = context.Animals.ToList();
    System.Console.WriteLine($"all animals : {JsonSerializer.Serialize(ConvertObject(animals), options)} \n");

    var dogAndCattle = context.Animals.FromSqlRaw("select * from \"Animals\" where animal_type = 1 or animal_type = 2").ToList();
    System.Console.WriteLine($"dog and cattle: {JsonSerializer.Serialize(ConvertObject(dogAndCattle), options)} \n");

    var dogs = context.Set<Dog>().ToList();
    System.Console.WriteLine($"dog : {JsonSerializer.Serialize(dogs, options)} \n");

    var cattles = context.Set<Cattle>().ToList();
    System.Console.WriteLine($"cattle : {JsonSerializer.Serialize(cattles, options)} \n");
}

private static IEnumerable<dynamic> ConvertObject(IEnumerable<Animal> animals)
{
    foreach (var animal in animals)
    {
        if (animal is Dog dog)
            yield return dog;
        else if (animal is Cattle cattle)
            yield return cattle;
        else
            yield return animal;
    }
}

个人总结

  • 也可以通过数据库view实现,但是创建了多张表
  • 这里只写的简单的操作,更多功能(如:不同子类相同字段映射表单个字段) 请移步到官网

原文地址:https://www.cnblogs.com/chilli-with-fish/p/15108128.html