#entity-framework #code-first #table-per-type
#entity-framework #сначала код #таблица для каждого типа
Вопрос:
Я пытаюсь написать проект, используя подход code-first, и я столкнулся со следующей проблемой
public class BaseType
{
[Key]
public int id { get; set; }
public string description { get; set; }
}
public class Type1 : BaseType
{
public decimal price { get; set; }
}
public class mycontext : DbContext
{
public DbSet<BaseType> basetypes { get; set; }
public DbSet<Type1> type1 { get; set; }
}
когда я запускаю приложение и создаю объект Type1 и использую mycontext.type1.ADD(mytype1object);
, и я смотрю на базу данных, таблица для первого типа содержит правильное поле, но в родительской таблице «базовые типы» также есть поле цены.
Должен ли я явно игнорировать поле?
Есть предложения?
Ответ №1:
По умолчанию code first будет использовать наследование TPH (таблица для иерархии). Это означает, что оба ваших типа хранятся в одной таблице, называемой «Базовые типы». Вы заметите, что оно также включает дополнительное поле, называемое «Дискриминатор». EF сохранит значение в этом поле, чтобы указать, к какому типу относится каждая запись.
Если вы хотите, чтобы ваши типы находились в разных таблицах, вам нужно настроить контекст для TPT (таблица для каждого типа). Вы можете украсить свои классы аннотацией данных с именем таблицы или вы могли бы использовать model binder. Ниже приведен способ аннотирования данных.
[Table("BaseTypes")]
public class BaseType
{
[Key]
public int id { get; set; }
public string description { get; set; }
}
[Table("Type1s")]
public class Type1 : BaseType
{
public decimal price { get; set; }
}
Ответ №2:
Я не могу воспроизвести вашу проблему — фактически, если я использую ту же модель с EF 4.1, в сгенерированной БД только есть BaseTypes
таблица, содержащая оба элемента BaseType
и Type1
— строки с BaseType
элементами просто имеют нулевое значение в качестве цены. Итак, в настоящее время вы используете не TPT, а TPH. Чтобы переключиться на TPT, вы могли бы аннотировать свой класс Type1
или использовать fluent API:
[Table("Type1s")]
public class Type1 : BaseType
{
public decimal price { get; set; }
}
Ответ №3:
Спасибо за ввод BrokenGlass и ckal. Я привязывал к пользователю аннотацию «Таблица (имя)» и fluent API, и я следовал всем шагам, и в итоге получалась таблица как для базовых типов, так и для Type1s, а таблица BaseTypes содержала поля для полей в Type1s.
Однако, после того, как я пошел дальше и создал имена таблиц для каждого из оставшихся классов в моей модели, я попробовал это, и все заработало.
Я не уверен, было ли это случайностью или я обнаружил ошибку, но сейчас все работает.
Еще раз спасибо за быстрые ответы.
Работоспособность восстановлена…. На данный момент!!!