Загрузка связанных данных EF через generic метод

В базе данных у меня хранится следующий класс. Каждый класс продукта имеет ссылку на категорию к которой принадлежит.

public class Product : BaseEntity
{
    public override int Id { get; set; }
    public string Name { get; set; }
    public int Amount { get; set; }

    public int CategoryId { get; set; }
    public Category Category { get; set; }

    public IEnumerable<Sale> Sales { get; set; }

    public Product()
    {
        Sales = new List<Sale>();
    }
}

Для загрузки продуктов из базы я использую следующую функцию.

public IEnumerable<T> GetAll()
{
    return db.Set<T>().ToList();
}

Проблема состоит в том, что при использовании Set я не могу загрузить связанные данные, такие как Категория. Как это можно реализовать?


Ответы (2 шт):

Автор решения: motpfofs

Возможно ли перебрать все продукты таким образом:

public IEnumerable<T> GetAll()
{
    var query = db.Set<T>();

    if (query.GetType() == typeof(IQueryable<Product>))
    {
        query = query.Include(c => (c as Product).Category);
    }

    if (query.GetType() == typeof(IQueryable<Product2>))
    {
        query = query.Include(c => (c as Product2).Category);
    }

    return query.ToList();
}
→ Ссылка
Автор решения: Aries

Под рукой нет чистого EF. Есть только EF Core, поэтому детали возможно придётся подправить, но суть должна быть ясна. Можно добавить дополнительное выражение, которое тоже передавать в качестве аргументов для загрузки данных, и в нём как раз использовать загрузку доп. зависимостей. Получается что-то вроде такого

private static IEnumerable<T> GetAll<T>(Func<IQueryable<T>, DbSet<T>> postAction = null) where T : class {
    return (postAction?.Invoke(db.Set<T>()) ?? db.Set<T>()).ToList();
}

А сам вызов будет выглядеть так:

    var a = GetAll<Product>(m => m.Include(m => m.Category));

Ну а без зависимостей остаётся просто:

    var a = GetAll<Product>();
→ Ссылка