Чтобы использовать таблицу для конкретного типа, используйте MapInheritedProperties
, чтобы сообщить EF, что свойства базового класса являются частью таблиц подкласса.
Для установок EntityTypeConfiguration:
public class MyEntityConfiguration : EntityTypeConfiguration<MyEntity>
{
public MyEntityConfiguration()
{
Map(x => x.MapInheritedProperties());
ToTable("MyEntities");
}
}
Если вы используете modelBuilder для настройки сущностей, тогда:
modelBuilder.Entity<MyEntity>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("MyEntities");
}
Изменить ниже (такжеВ отредактированном примере выше, MapInheritiedProperties должен предшествовать ToTable)
Если вы хотите дочерние отношения на уровне базового класса, то вы должны структурировать модель данных как Таблица для Иерархии, а не Таблица для Бетона, так как отношения FK1 к 1 между таблицами.У ModuleHistory не может быть FK, указывающего на «либо» FirstEntity или SecondEntity.
Возможно получить EF для сопоставления этого, хотя я не уверен в том, чтобы пытаться сделать это с Code-First .. Использование конфигураций сущностей:
Учитывая структуру класса из исходного примера:
public class FirstEntityConfiguration : EntityTypeConfiguration<FirstEntity>
{
public FirstEntityConfiguration()
{
Map(x => x.MapInheritedProperties());
ToTable("FirstEntity");
HasKey(x => x.Id);
HasMany(x => x.History)
.WithOptional(x => (FirstEntity)x.Module)
.Map(x => x.MapKey("ModuleId"));
}
}
public class SecondEntityConfiguration : SecondEntityConfiguration<SecondEntity>
{
public SecondEntityConfiguration()
{
Map(x => x.MapInheritedProperties());
ToTable("SecondEntity");
HasKey(x => x.Id);
HasMany(x => x.History)
.WithOptional(x => (SecondEntity)x.Parent)
.Map(x => x.MapKey("ModuleId"));
}
}
public class ModuleHistoryConfiguration : EntityTypeConfiguration<ModuleHistory>
{
public ModuleHistoryConfiguration()
{
ToTable("ModuleHistory");
HasKey(x => x.Id);
}
}
// This mapping is needed because ModuleHistory's reference to BaseEntity. EF needs to know there is a Key.
public class BaseEntityConfiguration : EntityTypeConfiguration<BaseEntity>
{
public BaseEntityConfiguration()
{
HasKey(x => x.Id);
}
}
Тогда, когда вы получите FirstEntity или SecondEntity, вы получите любую историю.
У этой реализации есть несколько серьезных предостережений:
- Вы потеряете ограничения FK для истории модулей, поэтому база данных не обеспечит защиту для сирот (без каскадного удаления) или исправитассоциации между историей и родителем.
- Вы должны взять на себя ответственность за PK в ваших таблицах TpCC, чтобы избежать возможности дублирования ключей между FirstEntity и SecondEntity.Варианты здесь включают общую последовательность между таблицами или использование UniqueIdentifier (/ w NewSequentialId ())
В конечном счете, хотя вам, вероятно, будет лучше с конфигурацией Table-per-Hierarchy, если вы хотите, чтобы дочерние ссылки вбазовый класс, в противном случае разделите историю на два класса и перенесите отношения в классы реализации.