0

我有一个自引用实体:

英孚映射

当我查询这个实体时..

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();

..但是有没有更好的方法来做到这一点?

4

1 回答 1

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;
}

这比我使用的第一种方法快 0.4-0.7 秒。(几乎和 Include 方法一样好,但实际上给了我所有级别。)添加 ASC 排序并打破循环将我的 27k 项目树缩短了 0.1-0.25 秒。




[原始(错误)答案]

一天没看这个,回过头来,整整用了 5 秒才想到怎么做。

var query = context.DispositionPossibilities
    .Include("ChildDispositions")
    .Where(x => x.AreaID == areaID)
    .Where(x => !x.ParentCode.HasValue)
    .Where(x => x.IsActive == true);

我运行了代码分析,这种方法在几乎所有情况下都表现得更好:
- 最值得注意的是,对于我最大的树,它有 4 个级别和大约 0.73 到 0.83 秒的约 27,400 个项目。
-- 对于小树 (<5,000),差异远不那么明显(小于 0.01 - 0.05 秒)

于 2013-06-20T18:44:52.447 回答