Entity Framework Code-First: Как вручную обновить базу данных? - PullRequest
22 голосов
/ 08 июля 2011

Я создал небольшое демонстрационное приложение WPF, которое использует EF Code-First для сохранения своих данных в БД SQL CE 4.0.Это работает нормально, если я не удаляю свойство из объекта модели.Например, если я удаляю «HosteBy» из этого класса .....

public class Dinner
{
    public int DinnerID { get; set; }
    public string Title { get; set; }   
    public DateTime EventDate { get; set; }
    public string Address { get; set; }
    public string HostedBy { get; set; }

    public virtual ICollection<RSVP> RSVPs { get; set; }
}

... он выдает это исключение:

Модель, поддерживающая 'NerdDinners'контекст изменился с момента создания базы данных.Либо удалите / обновите базу данных вручную, либо вызовите Database.SetInitializer с экземпляром IDatabaseInitializer.Например, стратегия DropCreateDatabaseIfModelChanges автоматически удалит и заново создаст базу данных и при необходимости заполнит ее новыми данными.

Ошибка сохраняется даже после удаления поля «HosteBy» вручную из базы данных.Что мне здесь не хватает?Нужно ли удалять / усекать БД или есть другое решение?

Ответы [ 5 ]

25 голосов
/ 21 ноября 2012

В первом сценарии, в котором вы изменили модель Code First, перед тем, как переходить и изменять базу данных вручную, нужно открыть консоль диспетчера пакетов (Nuget) и ввести:

update-database -verbose

За исключением - поскольку в этом случае вы удаляете столбец, он сообщит, что он собирается что-то удалить, и ничего не удалит, если вы явно не скажете, что все в порядке. Итак, вы набираете:

update-database -f -verbose

Теперь это удалит столбец, который вы имели в вашей модели. -verbose говорит, что показывает SQL, который он запускает. Если вы боитесь просто позволить ему удалить что-то и проверить SQL перед запуском, используйте:

update-database -f -script

Это вместо этого выведет SQL в скрипт, который вы можете просмотреть, и запустите вручную самостоятельно.

В случае, если вы продолжили и удалили столбец в базе данных вручную, теперь у вас есть более сложный сценарий; таблица EdmMetadata, описанная в другом ответе, содержит хэш всей базы данных, который теперь не соответствует самой базе данных. Вы можете запустить SQL вручную, чтобы вернуть базу данных так, как ожидает Entity Framework (как это было до того, как вы вручную изменили ее, что приводит ее обратно в соответствие с хешем), проверив, что у вас было раньше и как выглядит ваша база данных в настоящее время.

Если это неосуществимо, вы сейчас находитесь в самой уродливой части Entity Framework Code First. Вам нужно удалить хеш-таблицу и перепроектировать БД в файлы кода.

Имя хеш-таблицы зависит от версии EF. В более старом EF4, о котором вы спрашивали, он называется EdmMetadata. В более новой версии EF5 она называется __MigrationHistory (в разделе Системные таблицы в вашей базе данных, если вы ищете в SQL Server Management Studio). Вам нужно будет стереть это.

Хорошей новостью на втором этапе, обратном инжиниринге БД в коде, является то, что Microsoft выпустила инструмент для бета-тестирования, который сделает это за вас.

Прохождение реинжиниринга дБ и EF Power Tools

Вы можете пропустить многие первые шаги, поскольку они просто настраивают БД и добавляют к ней какую-то ерунду, чтобы продемонстрировать, что вам нужно сделать: Обратный Инженер, дБ.

Обновление:

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

add-migration WhateverYouWantToCallThis

Изменения в db EF Migrations, которые необходимо выполнить, появятся в сгенерированных командах C #. Теперь вам нужно поработать с ними, чтобы обойти проблемы с тем, что он пытается сделать (например, попытаться удалить уже удаленные столбцы), и поставить на место то, что ему нужно будет продвигать (например, добавив обратно таблица, которая у вас есть в вашей модели, но вы удалили ее вручную в вашей базе данных).

После того, как вы добавили это и запустили update-database -f, EF Code First просто с уверенностью примет, что вы обновили базу данных так, как она должна быть, и обновит ее хеш-код на основе конечного результата. Если вы сделали правильные изменения, теперь вы можете продолжить миграцию в обычном режиме. Если это по-прежнему вызывает ошибки, вы обычно можете скопировать команды переноса вручную куда-нибудь и удалить их. Восстановите базу данных из вашей резервной копии, снова добавьте перенос вручную и попробуйте снова. В худшем случае вы прибегаете к описанному выше шагу обратного инжиниринга.

3 голосов
/ 08 июля 2011

взгляните на

http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx

Шаг 5: Изменение нашей модели

2 голосов
/ 08 июля 2011

Если ваша база данных содержит какую-то странную таблицу с именем EdmMetadata, ваш контекст использует какой-то очень базовый уровень управления версиями базы данных.Когда он создал базу данных, он сохранил хэш вашей модели в эту таблицу и каждый раз, когда он строит модель для вашего приложения (когда вы впервые используете контекст после перезапуска приложения), он снова вычисляет хеш и сравнивает его с хешем, хранящимся вэтот стол.Это означает, что любое изменение в вашей модели приведет к другому хешу, и EF будет реагировать с исключением, которое вы видите.Ручное изменение в базе данных не поможет вам, потому что таблица содержит все еще старые данные.

Решения:

  • Удаление этой версии.Требуется удалить IncludeMetadataConvention, как описано здесь .
  • Обновление хэша.Это потребует обратной разработки алгоритма для вычисления хеша (например, Red Gate .NET Reflector, JetBrains dotPeek, SharpDevelop ILSpy или Telerik JustDecompile) и вычисления нового хеша из скомпилированной модели (или использования отражения для чтения внутреннего свойства из DbCompiledModel.ModelHash суже вычисленный хэш), который вы будете хранить в таблице EdmMetadata.
  • Удаление базы данных вручную и создание EF новой базы данных - вы потеряете все данные
  • Установка инициализатора на DropCreateDatabaseIfModelChanges- он автоматически удалит базу данных и создаст новую, если вы измените модель - вы потеряете все данные
0 голосов
/ 26 мая 2014

Три простых вещи, которые нужно помнить при работе над Code First

  1. Включение-миграция
  2. Add-Migration
  3. Update-Database

Все говорит само за себя.

Вам необходимо запустить эти команды в консоли диспетчера пакетов вручную. Я опоздал, но надеюсь, что это поможет

0 голосов
/ 22 апреля 2014

Ознакомьтесь с разделом этой статьи о миграции кода с существующей базы данных.
http://msdn.microsoft.com/en-us/data/dn579398

Иногда ваш проект и ваша база данных могут не синхронизироваться. Поэтому вам, возможно, придется повторно синхронизировать вашу схему на основе существующей базы данных.



1) Чтобы создать миграцию на основе существующей схемы:
Add-Migration InitialCreate

2) После этого запустите Update-Database, чтобы добавить запись в таблицу _MigrationsHistory, чтобы указать, что миграция завершена до существующей схемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...