|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Здравствуйте! Приложение ASP NET Core 3.1, использую EF Core 3.1.13. Есть класс сущности БД, объект которого хранит коллекцию объектов этого же класса подчиненные ему. В свою очередь объекты, которые он хранит у себя в коллекции, аналогично могут иметь коллекции с другими объектами подчиненные им этого же класса: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
Задача обойти всех потомков текущей группы до самого низа. Я это делаю с помощью обхода графа в ширину. Прямые потомки текущего объекта загружаются при запросе на него в БД и в алгоритме я их могу перебрать: Код: c# 1.
Проблема в том, что не прямые потомки объекта, т.е. потомки потомков, которые хранятся в коллекциях прямых потомков, уже не загружаются, и я их перебрать уже не могу. Как сделать, чтобы коллекции потомков подгружались? Алгоритм, который используя для перебора потомков объекта: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 17:15 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 17:28 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Насколько я знаю, ЕФ не может делать рекурсивные запросы. Тут как раз случай, когда имеет смысл делать прямой SQL-запрос с рекурсивным CTE (если это MS SQL). В других диалектах наверняка что-то подобное тоже есть. https://docs.microsoft.com/en-us/ef/core/querying/raw-sql ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 17:29 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Shocker.Pro https://docs.microsoft.com/ru-ru/ef/core/querying/related-data/eager Тут не прокатит, наверное, - у него кол-во уровней произвольное может быть (судя по схеме БД) ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 17:30 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
fkthat Тут не прокатит, наверное, - у него кол-во уровней произвольное может быть (судя по схеме БД) Вообще, если класс один и тот же, то что мешает грузануть все объекты в единую плоскую коллекцию, зачем обходить граф? Понятно, что тогда элементам нужно знать свою принадлежность корневой сущности, но это обычно меньшее зло ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 18:02 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Shocker.Pro Вообще, если класс один и тот же, то что мешает грузануть все объекты в единую плоскую коллекцию, зачем обходить граф? Тут изначально представление дерева в РБД сделано самым примитивным и неэффективным способом. Я бы посоветовал автору заглянуть в книгу "SQL Antipatterns" в главу "Naive Trees" - там описаны три намного лучших альтернативных способа. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 18:23 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
По-поводу рекурсивных запросов с CTE. ORM linq2db позволяет делать таковые. Если страшно вот так сразу перейти на сие божественное чудо с убогого EF (как же отказаться от поделия мелкософта?), то можно использовать библиотеку linq2db.EntityFrameworkCore . Эта библиотека упомянута в списке EF Core Tools & Extensions . ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 18:40 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
petalvik ORM linq2db позволяет делать таковые. Ради пары запросов менять весь ORM? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 19:08 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
fkthat Shocker.Pro Вообще, если класс один и тот же, то что мешает грузануть все объекты в единую плоскую коллекцию, зачем обходить граф? Тут изначально представление дерева в РБД сделано самым примитивным и неэффективным способом. Я бы посоветовал автору заглянуть в книгу "SQL Antipatterns" в главу "Naive Trees" - там описаны три намного лучших альтернативных способа. Тут уже поздно менять структуру - БД рабочая сданными, пользователи а ней уже работают ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 20:20 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Shocker.Pro fkthat Тут не прокатит, наверное, - у него кол-во уровней произвольное может быть (судя по схеме БД) Вообще, если класс один и тот же, то что мешает грузануть все объекты в единую плоскую коллекцию, зачем обходить граф? Понятно, что тогда элементам нужно знать свою принадлежность корневой сущности, но это обычно меньшее зло Вот тут не понял, мне же нужны потомки одного конкретного объекта. Если я всех выгружу в List, то как мне это поможет. Или вы имеете ввиду выгрузить всех, потом среди них найти нужного, а потом выбрать всех у кого в родителях стоит id нужного объекта? А как тогда сохранить иерархию кто кому подчиняется внутри? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 20:31 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
petalvik По-поводу рекурсивных запросов с CTE. ORM linq2db позволяет делать таковые. Если страшно вот так сразу перейти на сие божественное чудо с убогого EF (как же отказаться от поделия мелкософта?), то можно использовать библиотеку linq2db.EntityFrameworkCore . Эта библиотека упомянута в списке EF Core Tools & Extensions . Не знаком с данной библиотекой. Могли бы вы показать как в моем случае должен выглядеть запрос? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 20:42 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Vlad__i__mir А как тогда сохранить иерархию кто кому подчиняется внутри? Vlad__i__mir Задача обойти всех потомков текущей группы до самого низа. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 21:56 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Vlad__i__mir Тут уже поздно менять структуру - БД рабочая сданными, пользователи а ней уже работают Тогда CTE. Впрочем, при желании, все эти паттерны из книги, что я выше упоминал ("Nested Sets", "Closure Table", и "Path Enumeration") можно реализовать и не меняя существующую структуру. Просто сделать нужную дополнительную таблица и триггера на таблицу с деревом, которая у тебя уже есть, для обновления этой дополнительной таблицы. Ни имеющийся код, ни имеющуюся схему менять при этом не придется. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2021, 23:55 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Vlad__i__mir Как сделать, чтобы коллекции потомков подгружались? Забрать плоский список и собрать дерево на клиенте, не? fkthat Тогда CTE. CTE вообще для другого. Чекайте: для фильтрации потомков и поиска предков. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2021, 03:04 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
hVostt CTE вообще для другого. CTE не " вообще для другого", а еще и для другого. Но, в том числе и для этого. https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-ver15#examples (См. Пример "D") ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2021, 04:59 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Shocker.Pro Vlad__i__mir А как тогда сохранить иерархию кто кому подчиняется внутри? Vlad__i__mir Задача обойти всех потомков текущей группы до самого низа. Обойти и сохранить их в коллекцию в том порядке, в котором они идут - от самого высокого до того кто внизу структуры. В принципе при вашем варианте это наверное тоже можно реализовать - сперва найти прямых потомков по id, потом искать их потомков по id уже найденных потомков, получается тоже рекурсия, правда пока точно не знаю как её реализовать ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2021, 15:07 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Vlad__i__mir В принципе при вашем варианте это наверное тоже можно реализовать - сперва найти прямых потомков по id, потом искать их потомков по id уже найденных потомков, получается тоже рекурсия, правда пока точно не знаю как её реализовать Блин. Я же тебе сказал - CTE. И ссылки дал. Вытягиваешь всех потомков рекурсивно одним запросом в коллекцию объектов. Потом эту коллекцию объектов обходишь. Обходить её чередой из 100500 запросов к серверу ты зашибешься. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2021, 16:01 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
Vlad__i__mir, Давно, лет 100 назад, была такая задача. Сделал sql функцию, возвращающую таблицу (Id, ParentId) и параметром самый первый Id. Она легко вызывается и ее можно поджойнить в linq to entity запросе. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.08.2021, 13:57 |
|
Как динамически загружать коллекций сущностей Entity Framework
|
|||
---|---|---|---|
#18+
ЕвгенийВ Сделал sql функцию, возвращающую таблицу (Id, ParentId) и параметром самый первый Id. Если я правильно понял, то второе поле это AncestorId В общем-то да. Это всё, что нужно. И вместо функции можно было сделать вьюху. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2021, 23:49 |
|
|
start [/forum/topic.php?fid=17&tid=1349025]: |
0ms |
get settings: |
12ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
60ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
others: | 233ms |
total: | 404ms |
0 / 0 |