#c# #entity-framework #sql-server-2008
#c# #entity-framework #sql-server-2008
Вопрос:
У меня есть модель сущности со следующими объектами:
- Дом
- Задача
- TaskType
У меня есть следующие отношения: Дом <1>—-<> Задача (один ко многим) Задача <>—-<1> Тип задачи (многие к одному)
Теперь я хотел добавить отношение «многие ко многим» между House и TaskType, чтобы указать, какие типы задач доступны для house.
Каков правильный способ сделать это в Visual Studio 2010 без потери данных в базе данных.
Если я сделаю это на совершенно новой модели, в которой еще не создана база данных, она работает нормально, но если я попытаюсь добавить ее после того, как я сгенерировал базу данных в первый раз, я потеряю все свои данные, поскольку сгенерированный SQL удаляет все таблицы.
Если я попытаюсь вручную создать таблицу в БД под названием HouseTaskTypes с двумя столбцами (House_Id и TaskType_Id) с внешними ключами для House и TaskTypes, это выглядит странно, когда я обновляю модель из базы данных.
Вероятно, я могу заставить ее работать с некоторыми ручными настройками, но я хотел бы знать, каков правильный способ добавления ассоциации / отношения «многие ко многим» в уже существующую модель Entity Framework.
Все идеи приветствуются!
Ответ №1:
Перенос существующей схемы базы данных на новую не поддерживается в EF 4.1. Из msdn:
Code First не поддерживает миграцию существующей схемы базы данных. Entity Framework 4.1 поддерживает удаление и повторное создание схемы базы данных при изменении модели с помощью инициализаторов базы данных. Поддерживаются следующие инициализаторы: CreateDatabaseIfNotExist, DropCreateDatabaseAlways и DropCreateDatabaseIfModelChanges
Итак, чтобы решить вашу проблему, я бы
- установите для инициализатора значение CreateDatabaseIfNotExist или отключите его
- вручную добавьте таблицу в базу данных
- вручную добавьте свойства навигации в свою модель
- вручную сопоставьте отношение «многие ко многим» (см. Ниже)
- затем добавьте любые данные в новую таблицу либо через ваше приложение, либо вручную
Чтобы вручную сопоставить отношения, добавьте следующий метод в свой DbContext
class protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new HouseConfiguration()); `
}
Затем в том же или доступном пространстве имен, что и ваш класс DbContext, добавьте класс конфигурации для одной стороны отношения «многие ко многим». Цель этого класса — выполнить фактическое сопоставление. Обычно у меня есть отдельное пространство имен только для этих классов конфигурации.
class HouseConfiguration : EntityTypeConfiguration<House>
{
public HouseConfiguration()
{
// many-to-many w/tasktypes
this.HasMany(h => h.TaskTypes)
.WithMany(tt => tt.Houses)
.Map(m =>
{
m.ToTable("HouseTaskTypes");
m.MapLeftKey("HouseId");
m.MapRightKey("TaskTypeId");
});
}
}
Вам придется дважды проверить имена свойств / key names, но этого должно хватить.
Комментарии:
1. Это то, что я пытался сделать. Сначала я добавил промежуточную таблицу с двумя столбцами, один для идентификатора House_id и один для идентификатора TaskType_id. Это было сделано в SQL Server (2008 R2 Express) Затем я попытался добавить связь «многие ко многим» между объектом «House» и объектом «TaskType» в конструкторе моделей объектов в Visual Studio. Проблема в том, что я получаю сообщение об ошибке «Для следующего entityset / associationset не указано сопоставление». И поскольку таблица не отображается в разделе «Model Browser -> Store -> Tables / Views», я не могу сопоставить ее.