0

私は自己参照エンティティを持っています:

EF マッピング

このエンティティを照会すると..

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ソリューションは、階層全体を横断しません。これは私には明らかだったはずですが、階層の最初のレベルのみが返されます。

この呼び出しはツリーごとに 1 日に多くても 1 回行うため、パフォーマンスに影響を与えます。

そうは言っても、ルート以外の要素を階層から取り除くためのより良い方法を思いつきました。

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 秒速くなりました。(インクルード メソッドとほぼ同じですが、実際にはすべてのレベルが得られます。) ASC ソートを追加してループを抜け出すと、27,000 のアイテム ツリーが 0.1 ~ 0.25 秒短縮されました。




[元の(悪い)回答]

これを1日見ずに戻ってきた後、これを行う方法を考えるのに5秒かかりました.

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

私はコード プロファイリングを実行しましたが、この方法はほぼすべてのケースでパフォーマンスが向上しました

-- 小さなツリー (<5,000) の場合、違いはそれほど目立ちません (.01 ~ .05 秒未満)。

于 2013-06-20T18:44:52.447 に答える