Обновление модели entity framework 4 с отношением «многие ко многим», как?

#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», я не могу сопоставить ее.