Наследование сущностей 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 шт):

Автор решения: InterceptorTSK

Пример работы абстракций.

Есть абстракция котика, есть абстракция пёсика. И есть абстракция животного.

Постройте граф [дерево] абстракций. В данном случае граф - тривиален, это:

        Животное
        /      \
    Котик      Пёсик

Верифицируйте граф абстракций. Т.е. получите все возможные утверждения из этого графа, и вот же они:

  1. Котик - это котик
  2. Пёсик - это пёсик
  3. Животное - это животное
  4. Котик - это животное
  5. Пёсик - это животное

Если вы построите граф иначе - вы получите набор ложных утверждений.

Только из исправно построенного графа абстракций - можно получить набор истинных утверждений. И это очевидные утверждения, но есть вовсе не очевидные, вот они:

  1. Котик абстрагированный до животного - это животное
  2. Пёсик абстрагированный до животного - это животное

Но тут получается аццкий фокус. Прямиком из ада. Потому что иначе не скажешь. Потому что подавляющее большинство - к этому никогда не готовы.

Если котик - это котик, а пёсик - это пёсик, то они не равны. Но будучи абстрагированы к животному - равны. Разницы - нет. И как так? А вот так. Так работают абстракции. Они для того и есть. Были две абстракции, абстракция котика, абстракция пёсика. А стала одна - абстракция животного. Именно - одна . Потому что абстрагированного котика до животного и абстрагированного пёсика до животного - различить невозможно . Две абстракции животного - бессмысленны. Это же полные копии. Потому [доказательно] и существует ровно одна абстракция животного.

Суть аццкого [именно аццкого] фокуса тут в том, что пара чего либо - может быть равна, а может быть не равна, в пределах пары. Смотря до чего вы абстрагируете эту пару - такой ответ [утверждение] и получите. И такое работает только в абстракциях. Абстракции - заранее никогда не определены. И любые утверждения над абстракциями, заранее - никогда не определены.

Что такое "абстрагирование"? Это потеря информации до такой [нужной] степени, что бы любое иное [подходящее] тоже будучи способно потерять информацию - в итоге было сводимо к чему то одному [одинаковому/не различимому/не имеющему разницы], что называют родительской абстракцией.

И есть обратная операция - это "конкретизация". Это когда абстрактное приобретает информацию и становится менее абстрактным, т.е. более конкретным, это называется потомком, относительно родительской абстракции.

Суть тут в том, что например абстракцию "цвета", "кирпича", "квазиромбокубооктаэдра" и "большого адронного коллайдера" - вы в вышепостроенное дерево абстракций котика/пёсика/животного - никак не прилепите.

Потому что выше написано про "абстрагирование" - это такая степень потери информации, что бы у какого то А, и у какого то Б - получилась общая [одинаковая/не различимая] суть.

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

Тогда что делать? Строить графы абстракций) Если построенное дерево логически не противоречит само себе [в рамках самоописания самого себя] - значит это годное [не противоречивое] дерево.

Но деревьев много. И они абстрактно - не пересекаются. Никак. Есть дерево где есть абстракция "цвета", а есть дерево где есть абстракция "цены", и так далее. Но эти абстракции существуют в рамках собственных деревьев абстракций.

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

Но для каких либо связей [отношений] между деревьями - нужны интерфейсы.

→ Ссылка