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");
}