Как перечислить все предметы при использовании наследования? - PullRequest
0 голосов
/ 04 апреля 2020

Я пытаюсь работать с наследованием. У меня есть три модели

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

Если ядро ​​создало столбец «Дискриминатор», я могу отдельно перечислять кошек или собак и создавать новые предметы. Проблема в том, что я хотел бы перечислить всех животных с их уникальными свойствами. Например, если строка является Cat, выведите meowPerHour. Но mewPerHour не является свойством или методом в классе Animal. Я использую код ниже, чтобы напечатать всех животных.

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

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

Как я могу решить эту проблему?

1 Ответ

0 голосов
/ 04 апреля 2020

Вы можете использовать следующий подход, но будьте осторожны, так как этот подход с нетерпением загружает всех животных и может не подойти лучше всего для всех ваших случаев.

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;
}

Здесь мы получаем все Наборы сущностей, реализующие обобщенный c класс T. Этот метод может быть полезен, если вы нужно работать с интерфейсами.

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;
}

И метод извлечения всех наборов сущностей, полученных из обобщенного c класса T

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;

}

...