質問

I have a self-referencing entity:

EF Mapping

When I query this entity..

var query = this._context.DispositionPossibilities
    .Where(x => x.AreaID == areaID)
    .Where(x => x.IsActive == true);

.. the resulting collection has EVERY item returned from the query at the root, and then the those items with ParentIDs are 'duplicated' inside the child collections (because of Navigation Properties).

I can remove them by doing this:

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

.. But is there a better way to do this?

役に立ちましたか?

解決

[EDIT]
My original Include solution below does not traverse the entire hierarchy. This should've been obvious to me, but it will only return the FIRST level of the hierarchy.

Since I will be making this call per-tree at most once per day, I'll take the performance hit.

That said, I did come up with a better way to strip the non-root elements off the hierarchy:

var subset = new List<DispositionPossibility>();
foreach (var disp in query.OrderBy(x => x.ParentCode).ToArray())
{
    if (!disp.ParentCode.HasValue)
        subset.Add(disp);
    else
        break;
}

This wound up being .4-.7 seconds faster than the first method I was using. (So almost as good as the Include method, but actually giving me all levels.) Adding the ASC sort and breaking out of the loop shaved .1-.25 seconds off my 27k item trees.




[Original (BAD) Answer]

After not looking at this for a day and coming back to it, it took all of 5 seconds to think of how to do this.

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

I ran code profiling, and this method performs better in almost every case:
-- Most notably for my largest trees with 4 levels and ~27,400 items by roughly .73 to .83 seconds.
-- For small trees (<5,000), the difference was far less noticeable (less than .01 - .05 seconds)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top