Как 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.
У каждого из древовидных сценариев есть свои плюсы и минусы, это действительно хорошо описано в блоге Мортезы Манави.