Вместо того, чтобы сначала думать о компоновке базы данных, вы должны подумать о том, как бы вы представляли эти отношения в коде.В конце концов, вы используете подход, основанный на коде.
По сути, вы можете выбрать один из двух вариантов: либо у пациента есть несколько свойств, по одному для каждого типа свойства, либо существует только одна коллекция для всех свойств.:
public class Patient
{
// …
// option 1
public CancerType CancerType { get; set; }
public Dietary Dietary { get; set; }
public OtherProperty OtherProperty { get; set; }
// option 2
public IList<PatientProperty> Properties { get; set; }
}
Оба эти варианта имеют свои преимущества и недостатки.Хотя опция 1 является очень явной и предусматривает одно значение для каждого типа, она также требует наличия свойства (класса) для каждого свойства (пациента).Поэтому, если вы позже расширите свою модель, вам придется скорректировать модель своего пациента.
Преимущество варианта 2 заключается в том, что он может просто собрать все.Таким образом, вы можете просто добавить свойства своему пациенту, не изменяя модель позже, если вы введете новые свойства.Кроме того, он также будет напрямую поддерживать несколько вариантов выбора для одного вида.С другой стороны, он ничего не проверяет сам по себе, поэтому вам нужна бизнес-логика для фактического применения ваших правил.
Перемещение в базу данных, для варианта 2вам, очевидно, нужна таблица ссылок, так как сейчас это отношение «многие ко многим».Поскольку у вас есть только ссылка на базовый тип PatientProperty
, но вы действительно хотите поговорить о конкретном типе, вам понадобится какой-то дискриминатор .Дискриминаторы - это, по сути, просто нотация для дополнительного хранения вида объекта в базе данных.
При хранении данных с наследованием обычно делается «таблица на иерархию».Это означает, что все типы в иерархии базового типа PatientProperty
будут использовать одну и ту же таблицу.Столбец дискриминатора используется для указания типа, а дополнительные свойства, которые могут иметь некоторые типы свойств, реализованы со столбцами, допускающими обнуляемость.Эта установка работает из коробки с Entity Framework и описана в этой главе в документации .
Другой подход, «таблица на тип», не поддерживается в EF Core,поэтому, если вы хотите следовать этому, вам придется реализовать это самостоятельно.Но в вашем случае, когда типы свойств в основном очень похожи, я бы даже поспорил с этим и фактически оставил бы их в одной таблице.
Для варианта 1, если у вас есть только одно свойство каждогоВид назначен пациенту, все немного проще.Так как у вас там нет многих ко многим, вам на самом деле не нужна таблица ссылок.Вам просто нужно сохранить идентификатор для каждого связанного типа свойства в модели пациента, как показано в приведенном выше UML.При этом вы также можете сохранить типы свойств как отдельные типы, которые не разделяют одну таблицу в базе данных.