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);
Order
必须是从 EntityBase
派生的 class
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();
}
这里-
TEntity
不需要成为 EntityBase
类型的约束,因为我们没有使用 Id
属性
- 不需要参数
entity
,因为我们不是在寻找特定的实体
- 为了在调用代码中标识类型,调用方法时必须使用类型参数-
// Order has a Customer parent and a list of OrderLine children
var orderList = await _Repo.LoadAllWithRelatedAsync<Order>(p => p.Customer, p => OrderLines);
我创建了一个可以在我的项目中帮助我的 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);
Order
必须是从EntityBase
派生的 class
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();
}
这里-
TEntity
不需要成为EntityBase
类型的约束,因为我们没有使用Id
属性- 不需要参数
entity
,因为我们不是在寻找特定的实体 - 为了在调用代码中标识类型,调用方法时必须使用类型参数-
// Order has a Customer parent and a list of OrderLine children
var orderList = await _Repo.LoadAllWithRelatedAsync<Order>(p => p.Customer, p => OrderLines);