使用继承时如何列出所有项目?

How to list all items when using inheritance?

我正在尝试使用继承。我有三个型号

class Animal {string name;}
class Cat : Animal {int meowPerHour}
class Dog : Animal {bool mixedBreed}

Ef core 创建了一个鉴别器列,我可以单独列出猫或狗,我可以创建新项目。 问题是我想列出所有具有各自独特属性的动物。例如。如果该行是猫,则打印 meowPerHour。但是 mewPerHour 不是 属性 或 Animal Class 中的方法。我正在使用下面的代码打印所有动物。

public IList<Animal> Aniamls { get;set; }

public async Task OnGetAsync()
{
   Animals = await _context.Animal.ToListAsync();
}

我该如何解决这个问题?

您可以使用以下方法,但要小心这种方法会急切地加载所有动物,可能并不适合您的所有情况。

public IEnumerable<IAnimal> GetAllAnimals()
{
  List<IAnimal> allAnimals = GetAllEntriesByEntityInterface<IAnimal>();
  return allAnimals;
}

将所有实体合并到一个列表中的方法

private List<T> GetAllEntries<T>() where T : class
{
  List<IQueryable<T>> sets = typeof(T).IsInterface ? GetAllSetsByInterface<T>() : GetAllSetsByBaseClass<T>();

  List<T> allEntries = new List<T>();
  foreach (var item in sets)
  {
    allEntries.AddRange(item.ToList());
  }

  return allEntries;
}

这里我们获取所有实现 T 的泛型 class 的实体集。如果您需要使用接口,此方法可能很有用。

private List<IQueryable<T>> GetAllSetsByInterface<T>() where T : class
{
  var types = context.Model.GetEntityTypes().Select(t => t.ClrType).ToList().Where(t => t.GetInterfaces().Any(i => i == typeof(T))).ToList();
  var sets = types.Select(type =>
                      context.GetType()
                        .GetMethod("Set")
                        .MakeGenericMethod(type)
                        .Invoke(context, null)
                        as IQueryable<T>
                      ).ToList();
  return sets;
}

以及获取从 T

的泛型 class 派生的所有实体集的方法
private List<IQueryable<T>> GetAllSetsByBaseClass<T>() where T : class
{
  var types = context.Model.GetEntityTypes().Select(t => t.ClrType).Where(x => x.IsSubclassOf(typeof(T))).ToList();
  var sets = types.Select(type =>
                      context.GetType()
                        .GetMethod("Set")
                        .MakeGenericMethod(type)
                        .Invoke(context, null)
                        as IQueryable<T>
                      ).ToList();
  return sets;

}