【问题标题】:Entity Framework self-referencing entity query results are flat AND hiearchical实体框架自引用实体查询结果是平面和分层的
【发布时间】:2013-06-19 15:18:44
【问题描述】:

我有一个自引用实体:

当我查询这个实体时..

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

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

【问题讨论】:

    标签: entity-framework self-reference


    【解决方案1】:

    [编辑]
    我下面的原始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 项树缩短了 0.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 个级别和大约 0.73 到 0.83 秒的约 27,400 个项目。
    -- 对于小树 (

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      相关资源
      最近更新 更多