Хобрук: Ваш путь к мастерству в программировании

Получить рекурсивный rootID родительско-дочерней таблицы с помощью ef-core

У меня есть SQL-таблица, построенная как древовидный список (родительский дочерний). Означает, что у вас есть rootId и childId. У каждой сущности есть ParentId. Если ParentId имеет значение null, этот элемент является корневым.

Вот пример иерархической архитектуры

- Fruit (1)
  - TreeFruits (2)
    - Apple (4)
    - Bulb (5)
  - SeaFruits (3)
    - DeepSeaFruits (6)
      - Sushi (9)
      - Kraken (13)
    - Shrimp (7)
    - Fish (8)
- Vegetable (10)
  - Carrot (11)
  - Potato (12)

Вы можете видеть, что у каждого корневого элемента (номера 1 и 10) есть как минимум 1 дочерний элемент. Но глубинный размер элементов неизвестен.

Вот пример как выглядит таблица

------------
| Id*      |<---
|          |   |
| ParentId |----
| Name     |
------------

Моя задача — запросить (с помощью EntityFramework Core) RootId для данного фрукта. Конечно, я мог бы загрузить все сущности из базы данных и сделать это в памяти, но это не очень умно. У вас есть идеи, как я могу написать свой Linq, чтобы эта задача выполнялась в базе данных?


  • Это рекурсивный CTE, который не поддерживается EF. 17.02.2021
  • Знаете ли вы, можно ли вызвать этот CTE через linq-query, а также можно ли смоделировать этот CTE для модульного тестирования. 17.02.2021
  • Я узнал, как вызвать CTE в моем linq-запросе. Итак, теперь последний вопрос: как я могу смоделировать его для модульных тестов. 17.02.2021
  • Вызов CTE работает с DbFunction-Attribute, но я не знаю, как создать макет для модульного теста (см. stackoverflow.com/questions/53269315/). 18.02.2021

Ответы:


1

Если вы не хотите загружать все записи из базы данных, а затем обрабатывать их, у вас есть два варианта:

  • Решение 1. Напишите хранимую процедуру и выполните обработку в базе данных.

  • Решение 2. Напишите рекурсивную функцию, которая отправляет несколько запросов к базе данных (в размере корневой глубины)

Вот функция для решения 2:

    public async Task<int> GetRoot(int id)
    {
        var current = await _dbContext.Set<Entity>().Where(p => p.Id == id).FirstOrDefaultAsync();

        if (current.ParentId is not null)
        {
            return await GetRoot(current.ParentId.Value);
        }
        else
        {
            return current.Id;
        }
    }
    
21.05.2021
Новые материалы

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

Как построить любой стол
Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..