Наследование сущностей EF
Есть 2 разных контекста БД, и в каждом будет практически одинаковый набор сущностей, но некоторые из них слегка отличаются. Думал выделить общее в библиотеку и от нее уже унаследовать изменения, но возникли сомнения.
Допустим есть сущность PersonEntity. Как видно из примера ниже она ссылается на 6 других сущностей(A,B,..F), что является реальным примером(кроме именования). Между всеми этими сущностями установлена связь один ко многим.
public class PersonEntity
{
public int Id { get; set; }
public string Name { get; set; }
public AEntity A { get; set; }
public BEntity B { get; set; }
public CEntity C { get; set; }
public DEntity D { get; set; }
public EEntity E { get; set; }
public FEntity F { get; set; }
}
public class AEntity
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<PersonEntity> Persons { get; set; }
}
Что если для первого контекста я хочу оставить класс "AEntity" таким же, а для второго добавить в него новое свойство к примеру email. Ок, тогда я сделаю базовый класс и унаследуюсь от него два раза для каждого контекста.
public abstract class ABaseEntity<TPerson>
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<TPerson> Persons { get; set; }
}
public class AEntity : ABaseEntity<PersonEntity>
{
}
public class A2Entity : ABaseEntity<PersonEntity>
{
public string Email { get; set; }
}
А что если мне нужно проделать тоже самое, но для PersonEntity? Пусть для первого контекста будет AEntity, а для второго A2Entity и так для каждой из 6 зависимостей. Делать generic на 6 типов? Да, я могу, но думаю это плохая практика.
В данный момент сделал примерно такую реализацию, но может можно сделать еще лучше?
public abstract class PersonBaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
public class PersonEntity : PersonBaseEntity
{
public AEntity A { get; set; }
//Аналогично для остальных свойств
}
public class Person2Entity : PersonBaseEntity
{
public A2Entity A { get; set; }
//Аналогично для остальных свойств
}
P.S И как уследить, что в PersonEntity и в Person2Entity одинаковый набор свойств(A,B,C,D...)?
Ответы (1 шт):
Пример работы абстракций.
Есть абстракция котика, есть абстракция пёсика. И есть абстракция животного.
Постройте граф [дерево] абстракций. В данном случае граф - тривиален, это:
Животное
/ \
Котик Пёсик
Верифицируйте граф абстракций. Т.е. получите все возможные утверждения из этого графа, и вот же они:
- Котик - это котик
- Пёсик - это пёсик
- Животное - это животное
- Котик - это животное
- Пёсик - это животное
Если вы построите граф иначе - вы получите набор ложных утверждений.
Только из исправно построенного графа абстракций - можно получить набор истинных утверждений. И это очевидные утверждения, но есть вовсе не очевидные, вот они:
- Котик абстрагированный до животного - это животное
- Пёсик абстрагированный до животного - это животное
Но тут получается аццкий фокус. Прямиком из ада. Потому что иначе не скажешь. Потому что подавляющее большинство - к этому никогда не готовы.
Если котик - это котик, а пёсик - это пёсик, то они не равны. Но будучи абстрагированы к животному - равны. Разницы - нет. И как так? А вот так. Так работают абстракции. Они для того и есть. Были две абстракции, абстракция котика, абстракция пёсика. А стала одна - абстракция животного. Именно - одна . Потому что абстрагированного котика до животного и абстрагированного пёсика до животного - различить невозможно . Две абстракции животного - бессмысленны. Это же полные копии. Потому [доказательно] и существует ровно одна абстракция животного.
Суть аццкого [именно аццкого] фокуса тут в том, что пара чего либо - может быть равна, а может быть не равна, в пределах пары. Смотря до чего вы абстрагируете эту пару - такой ответ [утверждение] и получите. И такое работает только в абстракциях. Абстракции - заранее никогда не определены. И любые утверждения над абстракциями, заранее - никогда не определены.
Что такое "абстрагирование"? Это потеря информации до такой [нужной] степени, что бы любое иное [подходящее] тоже будучи способно потерять информацию - в итоге было сводимо к чему то одному [одинаковому/не различимому/не имеющему разницы], что называют родительской абстракцией.
И есть обратная операция - это "конкретизация". Это когда абстрактное приобретает информацию и становится менее абстрактным, т.е. более конкретным, это называется потомком, относительно родительской абстракции.
Суть тут в том, что например абстракцию "цвета", "кирпича", "квазиромбокубооктаэдра" и "большого адронного коллайдера" - вы в вышепостроенное дерево абстракций котика/пёсика/животного - никак не прилепите.
Потому что выше написано про "абстрагирование" - это такая степень потери информации, что бы у какого то А, и у какого то Б - получилась общая [одинаковая/не различимая] суть.
Как можно [до какой степени терять информацию о кирпиче], что бы абстрагировать кирпич до животного? Понятное дело - никак. Именно потому [и только потому, доказательно] - кирпич невозможно прилепить в дерево абстракций котика/пёсика/животного
Тогда что делать? Строить графы абстракций) Если построенное дерево логически не противоречит само себе [в рамках самоописания самого себя] - значит это годное [не противоречивое] дерево.
Но деревьев много. И они абстрактно - не пересекаются. Никак. Есть дерево где есть абстракция "цвета", а есть дерево где есть абстракция "цены", и так далее. Но эти абстракции существуют в рамках собственных деревьев абстракций.
Для того что бы описать дерево абстракций - нужно построить дерево, проверить дерево. И в этом дереве, понятное дело - хватит типичного наследования и полей.
Но для каких либо связей [отношений] между деревьями - нужны интерфейсы.