C# Иерархическая структура и Entity Framework 6

введите сюда описание изображенияВсем здравствуйте! Пишу простенькую программку для своего производства. C# изучаю довольно недавно и столкнулся с проблемой. Опишу цель и задачи, которые необходимо решить:

Программа на WinForms, доступ к БД MS SQL - Entity Framework 6.0. К примеру, фактически имеется множество деталей: деталь1, деталь2, деталь3 ... деталь150, у всех деталей есть поля:

<деталь1>

  • Наименование
  • Номер чертежа
  • Операция и т.п. Каждая деталь состоит из списка деталей, но каких-то деталей должно быть некоторое кол-во: {деталь3-3шт., деталь15-1шт., деталь45-450шт.} Каждая из этих деталей тоже в свою очередь состоит из каких-то деталей. Как бы казалось, что структура - простая иерархия, но только ровно до того момента, пока детали не пересекаются, например: Есть три детали - деталь1, деталь2 и деталь3:

<деталь1>

  • наименование
  • №чертежа
  • Состав: деталь4-1шт., деталь5-1шт., деталь6-35шт., деталь7-450шт.

<деталь2>

  • наименование -№чертежа
  • Состав: деталь8-1шт., деталь5-3шт., деталь7-300шт.

Тут как бы нет проблем и всё работает нормально и понятно, объекты сохраняются в БД без проблем. Но если в иерархию вступают ниже приведенная деталь, то нифига не получается:

<деталь3>

  • наименование
  • №чертежа
  • Состав: деталь9-1шт., деталь1-1шт., деталь2-10шт.

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

Теперь к задаче: мне необходимо в БД сохранить шаблон по которому будут создаваться заказы и отслеживаться их выполнение. К примеру: сначала в БД сохраняются шаблоны Деталей с их структурой, затем мне приходит заказ на "Деталь3" - я должен создать объекты по этому шаблону со структурой: <Деталь3>

  • Наименование: Деталь №3
  • №Чертежа: №1234
  • Состав: <Деталь8> {нужно - 1, сделано - 0} <Деталь5> {нужно - 3, сделано - 0} - Наименование - №чертежа - Состав: деталь4 {нужно - 1, сделано - 0} деталь5 {нужно - 1, сделано - 0} .... <Деталь2> {нужно - 10, сделано - 0} - Наименование - №чертежа - Состав: деталь4 {нужно - 1, сделано - 0} деталь5 {нужно - 1, сделано - 0} ....

Далее я изменяю кол-во изготовленных деталей с низа дерева до конечного изготовления детали3. Я уже битый месяц перебираю различные варианты реализации этой задачи, но не могу придумать структуру этих объектов. Если не сложно - помогите хотя бы направить на мысль в каком направлении смотреть..

В идеале - есть множество структур, состоящих из экземпляров класса Р. в каждой структуре есть дочерние экземпляры, в которых есть ещё дочерние и так сколько угодно. Но любой из экземпляров может быть и дочерним элементом совсем другой структуры. Я работаю с EntityFramework 6. В решении всё работает как положено, но при отправке объекта в БД SQL ругается на множественные ссылки, типа на один объект не могут ссылаться несколько объектов. Плюс ко всему каждый объект Р может иметь различные варианты исполнения (прим. Р2).


Ответы (1 шт):

Автор решения: Alexander Petrov

Существует несколько способов хранения иерархий в реляционных СУБД. Здесь описаны четыре основных: Иерархические структуры и деревья в SQL. Кроме того, возможны их комбинации.

У каждого из способов есть достоинства и недостатки. Следует определить, какие операции чаще всего будут нужны в нашем приложении и выбрать наиболее подходящий способ.

Потом нужно прикинуть, а подходит ли этот способ под нашу СУБД? В частности, для работы со списками смежности (adjacency list) необходимо, чтобы СУБД умела делать рекурсивные запросы в CTE. При использовании подмножеств необходимы триггеры для поддержания ссылочной целостности. Бывают некоторые СУБД, которые не имеют то или другое.

Далее смотрим на возможности выбранной СУБД. В некоторых есть встроенные средства для работы с иерархическими структурами. Например, в Sql Server есть тип hierarchyid, а в PostgreSQL есть расширение ltree. Оба являются реализаций матиреализованного пути. Этот способ, возможно, окажется не идеальным именно для нашего случая, но т. к. он встроен в СУБД, то наверняка окажется быстрым и более удобным для использования.

Далее, решаем, с помощью чего будем работать с базой данных. При использовании сырых SQL-запросов нам доступны все возможности. Но если берём ORM, то она ограничивает нас. И сперва следует поискать, может ли эта ORM на выбранной СУБД использовать тот или иной способ работы с иерархиями. Вот, например, нашлась такая статья: Hierarchy in the Entity Framework 6 with the hierarchyid type.

→ Ссылка