【问题标题】:Generic repository pattern ASP NET CORE Web Api: using include with async通用存储库模式 ASP NET CORE Web Api:使用包含和异步
【发布时间】:2020-02-15 21:11:38
【问题描述】:

我有以下问题。 我的示例模型如下所示:

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 序列化。

我的项目结构如下。 我有在我的控制器中使用的通用存储库模式

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

我试图完成的是找到一种方法,如何将相关设施类型包括在我在下面的方法中返回的培训中。

    [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();
    }

【问题讨论】:

  • 您刚刚注意到在尝试构建通用存储库时存在严重限制。我建议您不要使用它,而是利用 EntityFramework 本身,它已经是一个具有 DbSet&lt;T&gt; 类型的存储库。
  • 所以真的没有办法绕着它走吗?

标签: c# asp.net asp.net-core asp.net-web-api


【解决方案1】:

选项 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(更通用的方式):

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

【讨论】:

  • 好的,我在那个地方,但我不知道如何调用那个方法。无论如何,这是我应该经常使用的东西吗?
  • 这取决于您,如果项目包含太多需要类​​似操作的不同实体,那么您可以使用通用方法。有关详细信息,请参阅Generics
猜你喜欢
  • 1970-01-01
  • 2019-02-25
  • 2020-09-16
  • 2020-08-31
  • 2020-09-28
  • 2017-03-21
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
相关资源
最近更新 更多