EF Core:如何从通用存储库中的 table 和相关的 table 加载数据

EF Core: How to load data from a table and related tables in Generic Repository

我创建了一个可以在我的项目中帮助我的 Generic Repository

问题:

最近我在做一个项目,我想从一些相关的 table 中获取数据 (所有数据来自一个 table 并从中加载所有相关数据我 select) 的其他 table,我创建的存储库也无法处理这个我也不想直接使用 Entity Framework Core。

我的仓库:

我的仓库是一个开源项目,你可以查看源代码from here

我想要的正是:

我的想法是在我的 generic repository 中创建一个方法,这个方法将接收我想要 select 数据的实体,并接收一个表达式,告诉它​​从气味实体和一些相关的 tables (不是所有相关的 table 但一些相关的 table 我将在表达式中发送).

我该如何解决这个问题?

这在很大程度上取决于您对通用存储库的具体实现,但以下代码可能会帮助您理解 -

public async Task<TEntity> LoadSingleWithRelatedAsync<TEntity>(TEntity entity, params Expression<Func<TEntity, object>>[] expressionList) where TEntity : EntityBase
{
    if (entity == null)
        return null;

    var query = _DbCtx.Set<TEntity>().AsQueryable();
    foreach (var expression in expressionList)
    {
        query = query.Include(expression);
    }

    return await query.FirstOrDefaultAsync(p => p.Id == entity.Id);
}

其中 EntityBase 是 -

public class EntityBase
{
    public int Id { get; set; }
}

以下是您将如何使用它的示例 -

// Order has a Customer parent and a list of OrderLine children
var loadedOrder = await _Repo.LoadSingleWithRelatedAsync(order, p => p.Customer, p => OrderLines);
  1. Order 必须是从 EntityBase
  2. 派生的 class
  3. order 可以是 Detached 实体(例如,通过客户端的方法参数接收),或从数据库中获取的现有实体

编辑:2021.04.01
如果您想要一个集合而不是单个实体,该方法可能类似于 -

public async Task<IEnumerable<TEntity>> LoadAllWithRelatedAsync<TEntity>(params Expression<Func<TEntity, object>>[] expressionList) where TEntity : class
{
    var query = _DbCtx.Set<TEntity>().AsQueryable();
    foreach (var expression in expressionList)
    {
        query = query.Include(expression);
    }

    return await query.ToListAsync();
}

这里-

  1. TEntity 不需要成为 EntityBase 类型的约束,因为我们没有使用 Id 属性
  2. 不需要参数entity,因为我们不是在寻找特定的实体
  3. 为了在调用代码中标识类型,调用方法时必须使用类型参数-
// Order has a Customer parent and a list of OrderLine children
var orderList = await _Repo.LoadAllWithRelatedAsync<Order>(p => p.Customer, p => OrderLines);