Entity Framework результаты запроса самоссылающейся сущности являются плоскими и иерархическими
У меня есть самоссылающаяся сущность:
Когда я запрашиваю эту сущность..
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();
.. Но есть ли лучший способ сделать это?
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;
}
Это оказалось на 0,4-7 секунд быстрее, чем первый метод, который я использовал. (Это почти так же хорошо, как метод Include, но на самом деле дает мне все уровни.) Добавление сортировки ASC и выход из цикла сбрасывает.1-25 секунд от моих деревьев элементов 27k.
[Оригинальный (ПЛОХОЙ) ответ]
После того, как я не смотрел на это в течение дня и не возвращался к нему, потребовалось всего 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 предметов примерно на 0,73 - 0,83 секунды.
- Для небольших деревьев (<5000) разница была гораздо менее заметна (менее 0,01 - 0,05 секунд)