我有一个自引用实体:
当我查询这个实体时..
var query = this._context.DispositionPossibilities
.Where(x => x.AreaID == areaID)
.Where(x => x.IsActive == true);
..生成的集合包含从根查询返回的每个项目,然后具有ParentID的那些项目在子集合中被“复制”(由于导航属性)。
我可以通过这样做删除它们:
// have to ToArray() first because the child entities will be excluded if I don't..
rValue = query.ToArray();
// trim off the entities at the root that shouldn't be there..
rValue = rValue.Where(x => !x.ParentCode.HasValue).ToArray();
..但有更好的方法吗?
答案 0 :(得分:4)
<强> [编辑] 强>
我下面的原始Include
解决方案不会遍历整个层次结构。这对我来说应该是显而易见的,但它只会返回层次结构的第一级。
由于我每天最多会对每个树进行一次这样的调用,所以我会受到性能影响。
那就是说,我确实提出了一种更好的方法来剥离层次结构中的非根元素:
var subset = new List<DispositionPossibility>();
foreach (var disp in query.OrderBy(x => x.ParentCode).ToArray())
{
if (!disp.ParentCode.HasValue)
subset.Add(disp);
else
break;
}
这比我使用的第一种方法快<4> .7秒。 (所以几乎和Include方法一样好,但实际上给了我所有级别。)
添加ASC排序并突破循环,使我的27k项目树减少.1-.25秒。
在没有看到这一天并回到它之后,花了5秒钟才想到如何做到这一点。
var query = context.DispositionPossibilities
.Include("ChildDispositions")
.Where(x => x.AreaID == areaID)
.Where(x => !x.ParentCode.HasValue)
.Where(x => x.IsActive == true);
我运行了代码分析,这种方法几乎在所有情况下都表现得更好:
- 最值得注意的是我最大的树木有4个等级,约27,400个物品约为73到0.83秒。
- 对于小树(<5,000),差异远不那么明显(小于.01 - .05秒)