Entity Framework 4.1 Модель поддержки контекста изменилась с момента создания базы данных сразу после создания БД - PullRequest
24 голосов
/ 28 октября 2011

Я работаю над проектом, который использует Entity Framework 4.1 для сохранения наших различных объектов в базе данных (сначала код).

Я тестирую в Visual Studio с локальной базой данных SQL Express, и наш сервер Jenkins развертывает принятый код на тестовом сервере. Когда это происходит, я временно изменяю строку локального соединения, чтобы указать на тестирующий сервер БД, и запускаю модульный тест, чтобы заново создать тестовую базу данных, чтобы она соответствовала нашим последним объектам и т. Д.

Я недавно заметил, что наш тестовый сервер выдает эту ошибку:

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

Обычно это указывает на то, что наш код изменился, и мне нужно запустить модульный тест, чтобы заново создать базу данных. За исключением того, что я только что сделал это! Я не верю, что с нашим процессом развертывания что-то не так - библиотеки DLL на тестовом сервере имеют те же версии, что и в моей локальной среде. Существуют ли какие-либо другие параметры или факторы среды, которые могут вызвать эту ошибку при изменении модели с момента создания базы данных?

Я новичок здесь - спасибо за любую помощь!

Ответы [ 7 ]

25 голосов
/ 16 декабря 2011

Ошибка, которую вы видите, означает, что хеш модели, сохраненный в таблице EdmMetadata, отличается от хеша модели, вычисленного из модели в приложении. Поскольку вы запускаете создание базы данных из другого приложения (вашего разработчика), возможно, что эти два отличаются. Вот простой совет: не используйте разные приложения для создания базы данных, а вместо этого позвольте основному приложению создать базу данных (автоматически или, например, с некоторым интерфейсом администратора).

В качестве другого варианта вы сможете полностью отключить эту проверку, удалив соглашение, ответственное за эти проверки:

modelBuilder.Conventions.Remove<IncludeMetadataConvention>();

Расчет хеша модели зависит от текущих сущностей в вашем приложении (любой простой результат изменения в хеше другой модели) и от версий / манифеста сервера базы данных. Например, модель, развернутая на SQL Server 2005 и 2008, будет иметь разный хеш модели (Express против Full или 2008 против 2008 R2 не должны приводить к разным хэшам модели).

9 голосов
/ 16 декабря 2011

Это может произойти из-за различий в порядке следования на разных платформах. Чтобы проверить, вы можете использовать API EdmxWriter для сравнения EDMX из обеих сред. Если какая-либо из таблиц имеет другой порядок столбцов, то это проблема.

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

Мы собираемся исправить эту проблему в следующем выпуске.

6 голосов
/ 20 декабря 2011

В подходе «сначала код» SSDL генерируется во время выполнения кода. Одной из сведений, включенных в сгенерированный SSDL, является имя провайдера, используемого в DbConnection. Как вы сказали, вы подключаетесь к разным ядрам баз данных, поэтому вы должны использовать двух разных провайдеров. Это полностью меняет вывод функции хеширования.

Приведенный ниже код был извлечен из сборки EntityFramework:

using (XmlWriter writer = XmlWriter.Create(output, settings))
{
    new SsdlSerializer().Serialize(database, providerInfo.ProviderInvariantName, providerInfo.ProviderManifestToken, writer);
}
3 голосов
/ 17 декабря 2011

На двух серверах, на которых работает ваше приложение, работают разные операционные системы (или пакеты обновления?) Похоже, что используемый SHA256CryptoService может вызвать исключение PlatformNotSupportedException, которое вызывает его откат к другому методу.

// System.Data.Entity.Internal.CodeFirstCachedMetadataWorkspace
private static SHA256 GetSha256HashAlgorithm()
{
  SHA256 result;
  try
  {
    result = new SHA256CryptoServiceProvider();
  }
  catch (PlatformNotSupportedException)
  {
    result = new SHA256Managed();
  }
  return result;
}

Вы можете проверить это, используя отражение для вызова следующих 2 (внутренних / частных) методов на каждом сервере.

MetaDataWorkspace.ToMetadataWorkspace(DbDatabaseMapping, Action<string>)
CodeFirstCachedMetadataWorkspace.ComputeSha256Hash(string xml);
3 голосов
/ 16 декабря 2011

Это может помочь, и ссылка на блог Скотта G, безусловно, решит вашу проблему. Проверьте этот вопрос ссылка

Изменить 1: это ссылка на Скотта Gblog

Edit 2: Вы также можете проверить this , если сначала используете базу данных на сервере интеграции

Edit 3: Это более подробноответ как у Скотта G

2 голосов
/ 07 ноября 2011

Код Entity Framework сначала создает таблицу с именем EdmMetadata. Он хранит хэш вашей текущей модели. После запуска приложения EF проверяет, совпадает ли используемая модель с моделью, о которой БД «знает».

Если вы хотите выполнить миграцию базы данных, я предлагаю вам использовать EF Code для первой миграции , хотя это все еще альфа.

Если вы не хотите использовать миграцию, вы можете:

обрабатывает изменение схемы вручную - это означает перемещение содержимого таблицы EdmMetadata на тестовый сервер вместе со всеми изменениями

или

установите инициализатор базы данных в DropCreateDatabaseIfModelChanges (или, лучше, что-то из него полученное, и используйте метод Seed () для записи исходных данных). Чтобы установить инициализатор, либо вызовите Database.SetInitializer () при запуске приложения, либо используйте appSettings

<add key="DatabaseInitializerForType Fully.Qualified.Name.Of.Your.DbContext," value="Fully.Qualified.Name.Of.The.Initializer" />
0 голосов
/ 21 февраля 2013

Я только случайно переименовал свой файл .mdf и получил эту ошибку. Так что ищи это.

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