Как EF отображает неабстрактные базовые типы, когда ToTable не вызывается?

Я использую EF5 Code-first с классами сущностей следующим образом:

public class Base {
    public int Id { get; set; }
}

public class Derived : Base { // there are other derived types as well
}

и затем я настраиваю производную сущность следующим образом:

var config = new EntityTypeConfiguration<Base>();
config.Map<Derived>(m =>
{
    m.MapInheritedProperties();
    m.ToTable("derived");
});

DbModelBuilder modelBuilder = ...
modelBuilder.Configurations.Add(config);

В моем заявлении я тогда называю:

new MyDbContext().Set<Derived>().First();

Каково ожидаемое поведение для этого вызова?

Как ни странно, я, кажется, получаю противоречивое поведение для иерархий, настроенных точно так же. Иногда это не удается, потому что он пытается запросить "dbo.Base", а иногда он правильно запрашивает "dbo.Derived".

1 ответ

Значением по умолчанию для отображения производного типа EF является Таблица на иерархию. Вы можете получить все значения по умолчанию в этом блоге

На вашей базовой таблице будет добавлено новое поле с именем "Дискриминатор", и все поля в производном типе будут созданы в базе данных с пустым столбцом.

В вашем случае это должен быть TPT, поэтому таблица "base" будет содержать все поля базового класса, а таблица "производная" будет содержать все поля производного класса. Обе таблицы будут иметь общий первичный ключ.

Из блога: Существует три разных подхода к представлению иерархии наследования:

  • Таблица на иерархию (TPH): включите полиморфизм путем денормализации схемы SQL и используйте столбец дискриминатора типа, который содержит информацию о типе.
  • Таблица для типа (TPT): представляет отношения "является" (наследование) как отношения "имеет" (внешний ключ).
  • Таблица для конкретного класса (TPC): полностью исключить полиморфизм и отношения наследования из схемы SQL.

У каждого из древовидных сценариев есть свои плюсы и минусы, это действительно хорошо описано в блоге Мортезы Манави.

Другие вопросы по тегам