我正在开发一个 dotnet 核心项目,在该项目中我使用存储库模式并在中介处理程序中使用存储库。
我在存储库中有一个方法,它从数据库返回多条记录:
public List<T> GetAll(List<Expression<Func<T, object>>>? includes = null)
{
IQueryable<T> query = _dbSet.AsQueryable();
if (includes != null)
{
query = includes.Aggregate(query, (current, include) => current.Include(include));
}
return query.AsNoTracking().ToList();
}
我在处理程序中提供包含内容,如下所示:
public async Task<List<Office>> Handle(Office request, CancellationToken cancellationToken)
{
var includes = new List<Expression<Func<Office, object>>>
{
c => c.OfficeAddresses,
c => c.OfficeDepartments.Select(d => d.Department).Select(cc => cc.Phones),
};
return await _repository.GetAll(includes: includes);
}
我收到错误:
表达式“c.OfficeDepartments.AsQueryable().Select(x => x.Department)”在“Include”操作中无效,因为它不表示属性访问:“t => t.MyProperty”。要定位在派生类型上声明的导航,请使用强制转换 ('t => ((Derived)t).MyProperty') 或 'as' 运算符 ('t => (t as Derived).MyProperty')。可以通过组合Where、OrderBy(降序)、ThenBy(降序)、Skip 或 Take 操作来过滤集合导航访问
实体框架(核心)本身已经是一个存储库/工作单元。因此,坦率地说,围绕 EF 编写 repo/UOW 包装器是毫无意义的。事实上,这比毫无意义更糟糕,它非常有害,因为您提供的包装器甚至没有抽象出任何底层 EF 概念。处理程序应该对底层数据存储一无所知,但可怕的非抽象迫使它这样做。
将你的
IRepository
扔进垃圾箱,然后按以下方式重写你的代码:
Store
层,每个方法都接受包含要获取的数据详细信息的请求类型 DTO/POCO。这些方法使用 EF Core 与数据库通信并返回一个或多个 DTO/POCO。 这些方法是完全独立的,不会暴露正在使用的实际数据存储接口的任何细节。Handler
层依赖于 Store
。 Handler
构造发送到数据库的请求,并将这些请求映射到响应。一个 Handler
方法可以调用多个 Store
方法来完成它所需要的。