Entity Framework Добавить столбец дискриминатора только для одной дочерней модели

У меня есть одна родительская модель, которая является абстрактной, поэтому ее нельзя создать, и в настоящее время у меня есть один дочерний класс, который наследует ее. Например, у меня есть что-то вроде этого:

public abstract class Parent {
     public virtual int Id { get; set; }
}

public class Child1 : Parent {
     public override int Id { get; set; }
     public string SomeAttribute1 { get; set; }
     public string SomeAttribute2 { get; set; }
}

Я использую Entity Framework, чтобы заполнить мои модели БД, и когда я добавляю

public virtual IDbSet<Child1> Child1 { get; set; } в моем контексте я получаю следующую таблицу со следующими столбцами:

родитель:

  • Я бы
  • SomeAttribute1
  • SomeAttribute2

Что я и ожидал. Однако проблема, с которой я столкнулся, заключается в том, что, скорее всего, позже я добавлю больше дочерних моделей в этот родительский класс, например, другой класс, такой как:

public class Child2 : Parent {
     public override int Id { get; set; }
     public string Child2Attribute1 { get; set; }
     public string Child2Attribute2 { get; set; }
}

И когда я добавляю эту дочернюю модель в контекст, мой Parent столбец затем превращается в это:

родитель:

  • Я бы
  • SomeAttribute1
  • SomeAttribute2
  • Child2Attribute1
  • Child2Attribute2
  • дискриминатор

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

Я полагаю, что эти пустые значения дискриминатора впоследствии вызовут проблемы при попытке получить к ним доступ, поэтому мой вопрос заключается в том, существует ли способ навязать столбец дискриминатора в модели, которая имеет только 1 дочерний объект?

Или же есть лучший способ упреждающей обработки / подготовки к добавлению большего количества дочерних классов в более позднее время?

Или есть хороший способ, чтобы эти два дочерних класса были их собственными таблицами? Я никогда не делал много изящных ООП с Entity Framework, поэтому я не уверен, каким будет лучший способ решить эту проблему.

Спасибо за любую помощь!

РЕДАКТИРОВАТЬ

Я рассмотрел 3 различных модели наследования: TPH, TPT и TPC. TPH не является моделью, которая будет работать для моего сценария, однако могут работать и TPT, и TPC. Как я уже упоминал в ответах, у меня работает TPT, однако TPC идеально подходит для моего варианта использования, так как я не обязательно хочу / должен хранить родительский класс в базе данных (но все равно хотел бы его в моем контексте). Мне удалось заставить TPC почти работать, внеся следующие изменения в мой код:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Child1>().Map(m =>
    {
        m.MapInheritedProperties();
        m.ToTable("Child1");
    });

    modelBuilder.Entity<Child2>().Map(m =>
    {
        m.MapInheritedProperties();
        m.ToTable("Child2");
    });
}

и изменив мою родительскую модель на:

public abstract class Parent {
    [DatabaseGenerated(DatabaseGenerationOption.Identity)]
    public virtual int Id { get; set; }
}

Однако проблема, с которой я сталкиваюсь, заключается в том, что идентификаторы, заполняемые детьми, не являются уникальными (т.е. оба Child1 а также Child2 может иметь Id = 1, однако это означает, что есть 2 Parent объекты с Id = 1, что нарушает ограничения уникального ключа.

Есть ли способ, которым я могу заставить автоматически генерируемые идентификаторы быть уникальными для детей?

1 ответ

Решение

Я нашел решение своей проблемы благодаря тому, что предложил Bradley Uffner:

Table-Per-Type добился цели, просто добавив в контекст только родительский класс, а затем создав отдельные таблицы для каждого дочернего класса по мере их добавления следующим образом:

public virtual IDbSet<Parent> Parents { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<Child1>().ToTable("Child1");
     modelBuilder.Entity<Child2>().ToTable("Child2");
}
Другие вопросы по тегам