Entity framework core EF核心:可重复使用的IQueryable细分策略;仅加载选定属性
我正在实体框架核心中寻找一种高效地生成和重用部分(相当大)查询的方法 我的目标如下:Entity framework core EF核心:可重复使用的IQueryable细分策略;仅加载选定属性,entity-framework-core,iqueryable,Entity Framework Core,Iqueryable,我正在实体框架核心中寻找一种高效地生成和重用部分(相当大)查询的方法 我的目标如下: 生成高效的SQL;包括仅返回列 需要从相关子表中删除,并避免N+1场景 抽象并分离从grand child级别及其以下运行的queryable部分(thenClude()的第一个级别),因为查询的这部分将用于具有公共grand child实体的其他父级实体,我希望保持代码干燥 我当前的查询类似于以下(简化)示例: var itemtailsquery=getQueryable(x=>x.Id==itemId);
var itemtailsquery=getQueryable(x=>x.Id==itemId);
var item=await itemDetailsQuery.FirstOrDefaultAsync();
私有IQueryable getQueryable(表达式谓词)
{
return\u itemRepository
.GetAll()
.Where(谓词)
.Include(x=>x.ItemChildren)
.然后包括(x=>x.items孙子)
.然后包括(x=>x.itemGreat孙子1)
.Include(x=>x.ItemChildren)
.然后包括(x=>x.items孙子)
.然后包括(x=>x.Item曾孙2)
.Include(x=>x.ItemChildren)
.然后包括(x=>x.items孙子)
.然后包括(x=>x.Item曾孙3)
.然后包括(x=>x.Item曾孙)
。然后包括(x=>x.items曾孙子女);
}
上述方法可行,但:
private IQueryable<Item> getQueryable(Expression<Func<Item,bool>> predicate)
{
return _itemRepository
.GetAll()
.AsExpandable()
.Where(predicate)
.Select(x => new Item
{
Id = x.Id,
Name = x.Name,
ItemChildren = x.ItemChildren.AsQueryable().Select(ItemChild.Projection).ToList(),
});
}
private IQueryable getQueryable(表达式谓词)
{
return\u itemRepository
.GetAll()
.AsExpandable()
.Where(谓词)
.选择(x=>新项目
{
Id=x.Id,
Name=x.Name,
ItemChildren=x.ItemChildren.AsQueryable().Select(ItemChild.Projection).ToList(),
});
}
然而,当我尝试这个方法时,经过第二层子对象,没有加载任何内容;这可能是因为它没有被设计为以链式方式使用多层嵌套
我已经研究了其他策略,包括扩展方法,但尽管我可以让这些策略取代第一层包含,但我无法找到让这些策略取代第二层包含的方法,因此我可以执行以下操作:
private IQueryable<Item> getQueryable(Expression<Func<Item,bool>> predicate)
{
return _itemRepository
.GetAll()
.Where(predicate)
.Include(x => x.ItemChildren)
.IncludeGrandChildren();
}
private IIncludableQueryable<ItemGrandChildren, ItemGreatGrandChildren3> IncludeGrandChildren(this IQueryable<ItemGrandChildren> values)
{
return values
.Include(x => x.ItemGreatGrandChildren1)
.Include(x => x.ItemGreatGrandChildren2)
.Include(x => x.ItemGreatGrandChildren3)
.ThenInclude(x => x.ItemGreatGreatGrandChildren)
.ThenInclude(x => x.ItemGreatGreatGreatGrandChildren);
}
private IQueryable getQueryable(表达式谓词)
{
return\u itemRepository
.GetAll()
.Where(谓词)
.Include(x=>x.ItemChildren)
.IncludeGrandChildren();
}
私有IIIncludableQueryable IncludeGrandChildren(此IQueryable值)
{
返回值
.Include(x=>x.itemGreat孙子1)
.Include(x=>x.itemGreat孙子2)
.Include(x=>x.item曾孙3)
.然后包括(x=>x.Item曾孙)
。然后包括(x=>x.items曾孙子女);
}
我觉得我遗漏了或误解了一些基本的东西,但任何建议都将不胜感激。,AutoMapper等-所有这些都在某种程度上解决了相同的问题。@IvanStoev,谢谢你的提示。我简要地看了AutoMapper Queryable扩展,并对其进行了折扣,因为我想对其进行更多的控制r进程,尽管.ProjectTo()语法非常吸引人。我将进一步研究NeinLinq和LinqKit,AutoMapper等。-所有这些都在某种程度上解决了相同的问题。@IvanStoev,谢谢你的提示。我简要地看了一下AutoMapper可查询扩展,并对其进行了打折,因为我想对过程进行更多的控制,尽管.ProjectTo()语法非常吸引人。我将进一步调查NeinLinq和LinqKit。
private IQueryable<Item> getQueryable(Expression<Func<Item,bool>> predicate)
{
return _itemRepository
.GetAll()
.Where(predicate)
.Include(x => x.ItemChildren)
.IncludeGrandChildren();
}
private IIncludableQueryable<ItemGrandChildren, ItemGreatGrandChildren3> IncludeGrandChildren(this IQueryable<ItemGrandChildren> values)
{
return values
.Include(x => x.ItemGreatGrandChildren1)
.Include(x => x.ItemGreatGrandChildren2)
.Include(x => x.ItemGreatGrandChildren3)
.ThenInclude(x => x.ItemGreatGreatGrandChildren)
.ThenInclude(x => x.ItemGreatGreatGreatGrandChildren);
}