Generi c шаблон репозитория ASP NET CORE Web Api: использование include с асинхронным - PullRequest
0 голосов
/ 16 февраля 2020

У меня следующая проблема. Мои примерные модели выглядят следующим образом:

public class FacilityType
{
    public int Id { get; set; }
    public string Name { get; set; } 
    public bool IsDeleted { get; set; }
}

public class Training 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual FacilityType FacilityType { get; set; } 
    public int FacilityTypeID { get; set; } 
    public bool IsDeleted { get; set; }

}

Когда я создаю новый объект типа обучения, я хочу, чтобы он возвращался моим API с не только FacilityTypeID, но также FacilityType как объект, сериализованный в JSON.

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

public interface IGenericRepository<TEntity> where TEntity: class, IEntity
{
    IEnumerable<TEntity> GetAllEntities();
    Task<TEntity> GetEntityById(int id );
    Task CreateEntity(TEntity entity);
    Task UpdateEntity(int id, TEntity entity);
    Task DeleteEntity(int id);
}
public async Task<TEntity> GetEntityById(int id )
    {

        return await context.Set<TEntity>().Where(ent => ent.IsDeleted != true && ent.Id == id).FirstOrDefaultAsync();
    }   

И что я пытаюсь сделать sh - это найти способ, как включить связанный тип объекта в обучение, которое я возвращаю в методе ниже .

    [HttpGet("{id}")]
    public async Task<ActionResult<Training>> GetTraining(int id)
    {
         return await repository.GetEntityById(id);

    }

Заранее благодарен за ваш вклад :)

PS:

Является ли использование предикатов в параметре методов хорошей идеей? Вот так: И, кстати. как вызвать такой метод, например, с помощью выражения linq?

   public async Task<ICollection<TEntity>> GetEntityById(Expression<Func<TEntity, bool>> predicate)
    {

        //return await context.Set<TEntity>().Where(ent => ent.IsDeleted != true && ent.Id == id).FirstOrDefaultAsync();
        return await context.Set<TEntity>().Where(predicate).ToListAsync();
    }

1 Ответ

1 голос
/ 16 февраля 2020

Опция 1

Если у вас уже есть интерфейс IEntity, реализующий свойство Id:

public async Task<T> Get<T>(int id, Expression<Func<T, object>> include) where T : class, IEntity
{
    using (var context = new AppContext())
    {
        return await context.Set<T>()
                           .AsNoTracking()
                           .Where(x => x.Id == id)
                           .Include(include)
                           .FirstOrDefaultAsync();
    }
}

Для вызова этого метода:

var entity = await _context.Get<Training>(1, x => x.FacilityType);

Вариант 2

Без интерфейса IEntity (более общий c способ):

public async Task<T> Get<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> include) where T : class
{
    using (var context = new AppContext())
    {
        return await context.Set<T>()
                           .AsNoTracking()
                           .Where(predicate)
                           .Include(include)
                           .FirstOrDefaultAsync();
    }
}

Для вызова этого метода:

var entity = await _context.Get<Training>(x => x.Id == 1, x => x.FacilityType);
...