Подтвердить что ты не робот

Entity Framework 4.1. Модель, поддерживающая контекст, изменилась с момента создания базы данных сразу после создания базы данных

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

modelBuilder.Conventions.Remove<IncludeMetadataConvention>();

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

Ответ 2

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

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

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

Ответ 3

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

Следующий код был извлечен из сборки EntityFramework:

using (XmlWriter writer = XmlWriter.Create(output, settings))
{
    new SsdlSerializer().Serialize(database, providerInfo.ProviderInvariantName, providerInfo.ProviderManifestToken, writer);
}

Ответ 4

Это может помочь, и ссылка на блог Scott G обязательно будет решением вашей проблемы, проверьте этот вопрос ссылка

Изменить 1: это ссылка на блог Scott G

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

Редактировать 3: Это более подробный ответ как тот, который был у Скотта Г.

Ответ 5

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

http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256cryptoserviceprovider.sha256cryptoserviceprovider.aspx

// 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);

Ответ 6

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

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

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

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

или

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

<add key="DatabaseInitializerForType Fully.Qualified.Name.Of.Your.DbContext," value="Fully.Qualified.Name.Of.The.Initializer" />

Ответ 7

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