Entity Framework 4.1. Модель, поддерживающая контекст, изменилась с момента создания базы данных сразу после создания базы данных
Я работаю над проектом, который использует Entity Framework 4.1 для сохранения наших различных объектов в базе данных (сначала код).
Я тестирую Visual Studio с помощью локальной базы данных SQL Express, а наш сервер Jenkins разворачивает переданный код на тестовый сервер. Когда это произойдет, я временно изменю свою локальную строку подключения, чтобы указать на сервер тестирования тестирования, и запустите unit test, чтобы воссоздать тестовую базу данных так, чтобы она соответствовала нашим последним сущностям и т.д.
Недавно я заметил, что наш тестовый сервер сообщает об этой ошибке:
Модель, поддерживающая контекст "EntityFrameworkUnitOfWork", изменилась с момента создания базы данных. Либо вручную удалите/обновите базу данных, либо вызовите Database.SetInitializer с экземпляром IDatabaseInitializer. Например, стратегия DropCreateDatabaseIfModelChanges автоматически удалит и воссоздает базу данных и, возможно, запустит ее новыми данными.
Это обычно указывает на то, что наш код изменился, и мне нужно запустить unit test, чтобы заново создать базу данных. Кроме того, я просто сделал это! Я не верю, что с нашим процессом развертывания что-то не так - библиотеки DLL на тестовом сервере, похоже, такие же версии, как в моей локальной среде. Существуют ли какие-либо другие параметры или факторы среды, которые могут вызвать эту ошибку в отношении изменения модели с момента создания базы данных?
Я новичок здесь - спасибо за любую помощь!
Ответы
Ответ 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 и получил эту ошибку. Поэтому ищите это.