Модель, поддерживающая контекст <Database>, изменилась с момента создания базы данных

Сообщение об ошибке:

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

Я пытаюсь использовать функцию code-first, и следующее - это то, что я написал:

var modelBuilder = new ModelBuilder();
var model = modelBuilder.CreateModel();
using (AddressBook context = new AddressBook(model))
{
    var contact = new Contact
    {
        ContactID = 10000,
        FirstName = "Brian",
        LastName = "Lara",
        ModifiedDate = DateTime.Now,
        AddDate = DateTime.Now,
        Title = "Mr."

    };
    context.contacts.Add(contact);
    int result = context.SaveChanges();
    Console.WriteLine("Result :- "+ result.ToString());
}

Класс контекста:

public class AddressBook : DbContext
{
    public AddressBook()
    { }
    public AddressBook(DbModel AddressBook)
        : base(AddressBook)
    {

    }
    public DbSet<Contact> contacts { get; set; }
    public DbSet<Address> Addresses { get; set; }
}

и строка подключения:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <connectionStrings>
    <add name="AddressBook" providerName="System.Data.SqlClient"  
         connectionString="Data Source=MyMachine;Initial Catalog=AddressBook;
         Integrated Security=True;MultipleActiveResultSets=True;"/>
    </connectionStrings>
</configuration>

Итак, имя базы данных - "Адресная книга", и ошибка возникает, когда я пытаюсь добавить контактный объект в контекст. Я что-то пропустил здесь?

Ответ 1

Теперь это:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    Database.SetInitializer<YourDbContext>(null);
    base.OnModelCreating(modelBuilder);
}

в файле YourDbContext.cs.

Ответ 2

Вот некоторая информация из Scott Gu Blog, опубликованная Джеффом о том, что на самом деле происходит:

Для тех, кто видит это исключение:

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

Вот что происходит и что с этим делать:

Когда модель сначала создается, мы запускаем DatabaseInitializer, чтобы сделать такие вещи, как создание базы данных, если она отсутствует или добавить данные семени. По умолчанию DatabaseInitializer пытается сравнить схему базы данных необходимо использовать модель с хешем схемы, хранящейся в Таблица EdmMetadata, созданная с помощью базы данных (когда Code First тот, который создает базу данных). Существующие базы данных не будут иметь Таблица EdmMetadata и поэтому не имеет хеша... и реализации сегодня будет бросать, если эта таблица отсутствует. Мы будем работать над изменением этого прежде чем мы отправим версию fial, так как она по умолчанию. До тех пор существующие базы данных обычно не нуждаются в какой-либо базе данных инициализатор, поэтому его можно отключить для вашего типа контекста, вызвав:

Database.SetInitializer<YourDbContext>(null);

Джефф

Ответ 3

Для Entity Framework 5.0.0.0 - 6.1.3

Вы действительно хотите сделать следующее:

1. using System.Data.Entity;   to startup file (console app --> Program.cs / mvc --> global.asax
2. Database.SetInitializer<YourDatabaseContext>(null);

Да, Мэтт Фрир прав. ОБНОВЛЕНИЕ -EDIT: Предостережение заключается в том, что я согласен с другими в том, что вместо добавления этого кода в global.asax, добавляемый в ваш класс DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // other code 
    Database.SetInitializer<YOURContext>(null);
    // more code here.
}

Как уже упоминалось, это также хорошо для модульного тестирования.

В настоящее время я использую это с Entity Framework 6.1.3/.net 4.6.1

Я вернусь, чтобы предоставить фрагмент кода в ближайшем будущем.

Ответ 4

Это исправление больше не работает после CTP5.

Вы должны сделать Database.SetInitializer<YourContext>(null);

Ответ 5

Просто запустите команду followng sql в SQL Server Management Studio:

delete FROM [dbo].[__MigrationHistory]

Ответ 6

Только что узнал ответ и подумал об обновлении здесь. Просто нужно сделать следующее.

public class AddressBook: DbContext
{
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
    modelBuilder.IncludeMetadataInDatabase = false;
   }
}

Ответ 7

Или вы можете поместить эту строку в свой файл Global.asax.cs в Application_Start():

System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<ProjectName.Path.Context>());

Обязательно измените имя ProjectName.Path.Context на свое пространство имен и контекст. Если сначала использовать код, это приведет к удалению и созданию новой базы данных всякий раз, когда будут внесены какие-либо изменения в схему.

Ответ 8

Я потратил много дней, чтобы решить эту проблему, проанализировал множество разных сообщений и попробовал множество опций и окончательно зафиксировал . Это 2 проекта в моем решении с использованием первых миграций EF-кода:

  • Консольное приложение "DataModel", которое в основном используется как сборка, которая содержит все мои первые объекты кода, DbContext, Mirgations и общий репозиторий. Я включил в этот проект отдельный пустой файл локальной базы данных (в папке DataModel/App_Data), чтобы иметь возможность генерировать миграцию из консоли диспетчера пакетов.
  • WebApi, который ссылается на проект DataModel и использует файл локальной базы данных из папки WebApi/App_Data, который не включен в проект

Я получил эту ошибку при запросе WebApi...

Моя среда:

  • Windows 8.1 x64
  • Visual Studio 2015 Professional с обновлением 1
  • все мои проекты, предназначенные для .NET Framework 4.6.1
  • EntityFramework 6.1.3 из NuGet

Здесь я собрал все замечания, на которые вы должны обратить внимание, и все условия/требования, которые должны быть выполнены, чтобы избежать упомянутого исключения:

  • Вы должны использовать только одну версию пакета EntityFramework Nuget для всех проектов вашего решения.
  • База данных, созданная путем последовательного запуска всех сценариев миграции, должна иметь ту же структуру/схему, что и целевая база данных, и соответствовать модели сущности. Следующие 3 вещи должны точно соответствовать/отражать/соответствовать друг другу:
    • Вся ваша миграция script до последнего
    • Текущее состояние первой модели сущности (DbContext, entity)
    • Целевая база данных
  • Целевая база данных (файл mdf) должна обновляться/соответствовать последней миграции script. Убедитесь, что таблица "__MigrationHistory" в вашей целевой базе данных содержит записи для всех сценариев миграции, которые вы имеете, это означает, что все сценарии миграции были успешно применены к этой базе данных. Я рекомендую вам использовать Visual Studio для генерации правильных кодов первых сущностей и контекста, соответствующих вашей базе данных, Project → Добавить новый элемент → ADO.NET Entity Data Model → Code First из базы данных: Конечно, в качестве альтернативы, если у вас нет базы данных, вы можете написать модель вручную (код первых сущностей и контекста), а затем создать начальную миграцию и базу данных.
  • Название строки подключения, например. MyConnectionString в файле конфигурации запуска проекта (Web.config/App.config):

    <configuration>
      <connectionStrings>
        <add name="MyConnectionString" connectionString="...">
      </connectionStrings>
    <configuration>
    

    должен быть равен параметру, переданному в конструкторе вашего DbContext:

     public partial class MyDbContext : DbContext
     {
        public MyDbContext()
           : base("name=MyConnectionString"){}
        ...
    
  • Перед тем, как использовать Консоль диспетчера пакетов, убедитесь, что вы используете правильную базу данных для обновления или создания миграции, а необходимый проект задается как запускающий проект решения.. Для подключения к в базе данных он будет использовать строку подключения из этого файла .config, который в проекте, который задан как проект запуска.
  • И основной вопрос, который исправил мою проблему: Это странно, но в моей папке WebApi/bin DataModel.exe был стар, не обновлялся с момента последней сборки. Так как миграции были встроены в мою сборку DataModel.exe, то моя обновленная база данных WebApi использовала старые зеркала. Я был смущен, почему после обновления базы данных в WebApi он не соответствует последней миграции script из DataModel. Следующий код автоматически создает (если не существует) или обновляет последнюю локальную локальную миграцию в моей папке WebApi/App_Data.

       public class WebApiApplication : System.Web.HttpApplication
       {
           protected void Application_Start()
           {
               Database.SetInitializer(new MigrateDatabaseToLatestVersion<ODS_DbContext, Configuration>()); 
               ...
    

    Я попробовал очистить и перестроить решение, но это не помогло, чем я полностью удалил bin и obj из WebApi, удаленные файлы базы данных из WebApi/App_Data, встроенные, перезапущенные WebApi, сделали запрос к нему, создали корректную базу данных - ленивая инициализация (используя строки выше), что соответствует последней миграции и исключению больше не отображалось, Итак, это может решить вашу проблему:

    • удалить вручную bin, obj папки из вашего проекта запуска (который генерирует/обновляет вашу базу данных)
    • создайте свой проект запуска или лучше очистите и перестройте все ваши решения.
    • воссоздайте базу данных, запустив проект (выполнив строки выше) или воспользуйтесь командой "Обновление-база данных" диспетчера пакетов.
    • вручную проверьте, соответствует ли сгенерированная db и __MirgationHistory последней миграции script.

Ответ 9

Для меня с обновлением до 4.3.1 я просто обрезаю таблицу EdmMetaData или просто удаляю ее прямо.

Ответ 10

Для разработчиков VB.NET:

Добавьте следующую строку в файл Glabal.asax.vb в конце метода Application_Start()

Database.SetInitializer(Of ApplicationDbContext)(Nothing)

Измените ApplicationDbContext на конкретный контекст Db.

Ответ 11

У меня была эта проблема, и оказалось, что один проект указывал на SQLExpress, но тот, у кого проблема, указывал на LocalDb. (в их соответствующем web.config). Глупый надзор, но стоит отметить здесь, в случае, если кто-либо другой устранит эту проблему.

Ответ 12

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

Ответ 13

Я использую метод Database.CompatibleWithModel(доступный в EF5) для проверки соответствия модели и базы данных, прежде чем использовать ее. Я вызываю этот метод сразу после создания контекста...

        // test the context to see if the model is out of sync with the db...
        if (!MyContext.Database.CompatibleWithModel(true))
        {
            // delete the old version of the database...
            if (File.Exists(databaseFileName))
                File.Delete(databaseFileName);
            MyContext.Database.Initialize(true);

            // re-populate database

        }

Ответ 14

Это означает, что в контексте, который не был выполнен, произошли некоторые изменения. Сначала запустите Add-Migration, чтобы сгенерировать сделанные нами изменения (изменения, которые нам неизвестны) А затем запустите Update-Database

Ответ 15

На всякий случай у кого-то есть тот же сценарий, что и мой.

У меня есть база данных сначала EF и в то же время с использованием идентификатора asp.net

поэтому у меня есть два connectionStrings в моем webconfig, и с этим нет никаких проблем. Случилось так, что я создал/запустил скрипты для генерации вручную таблиц идентификаторов asp.net, которых я не должен.

поэтому DROP сначала создайте все идентификационные таблицы asp.net, созданные вами вручную/из сценариев.

DROP TABLE __MigrationHistory
DROP TABLE AspNetRoles
DROP TABLE AspNetUserClaims
DROP TABLE AspNetUserLogins
DROP TABLE AspNetUserRoles
DROP TABLE AspNetUsers

Ответ 16

Ни одно из этих решений не будет работать для нас (кроме отключения проверки схемы вообще). В итоге у нас был пропущенный матч в нашей версии Newtonsoft.json

Наш AppConfig не получил правильное обновление:

<dependentAssembly>
   <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
  </dependentAssembly>

Решение заключалось в том, чтобы исправить версию сборки до той, которую мы фактически развертывали

<dependentAssembly>
   <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="10.0.0.0" />
  </dependentAssembly>

Ответ 17

После некоторых исследований по этой теме я обнаружил, что ошибка происходит в основном, если у вас есть экземпляр db, созданный ранее на вашем локальном SQL-сервере Express. Поэтому всякий раз, когда вы обновляете db и пытаетесь обновить db/run некоторый код на db без выполнения команды Update Database, используя Package Manager Console; Прежде всего, вы должны удалить предыдущий db на нашем локальном SQL-Express вручную.

Кроме того, это решение работает, если у вас нет AutomaticMigrationsEnabled = false; в вашей конфигурации.

Если вы работаете с системой управления версиями (git, svn и т.д.), а некоторые другие разработчики обновляют объекты db на фазе производства, эта ошибка возрастает всякий раз, когда вы обновляете свою базу кода и запускаете приложение.

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

Ответ 18

Я читаю также книгу Pro ASP.NET MVC 4, и столкнулся с той же проблемой, с которой вы столкнулись. Для меня у меня возникла проблема после внесения изменений, предписанных в разделе "Добавление модели валидации" в книге. Как я решил проблему, переместив мою базу данных с localdb на полномасштабный сервер SQL Server 2012. (Кстати, я знаю, что мне повезло, что я могу перейти на полномасштабную версию, так что не ненавидите меня.;-))) Должно быть что-то с сообщением с db, которое вызывает проблему.

Ответ 19

Измените Global.asax.cs, включая событие Application_Start, с помощью:

Database.SetInitializer<YourDatabaseContext>(
 new DropCreateDatabaseIfModelChanges<YourDatabaseContext>());

Ответ 20

Проверьте следующие шаги

  • Database.SetInitializer(нуль); → в Global.asax.cs

2.   

  • ваше имя класса контекста должно совпадать с проверьте его

Ответ 21

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

У меня была эта ошибка, потому что я неправильно назвал локальную базу (глупая ошибка), а имя строки подключения в файле web.config "DefaultConnection" не соответствует MyDbContext i.e.

public MyDbContext(): base("DefaultConnection")
{}


<connectionStrings>
    <add name="DefaultConnection" ...
  </connectionStrings>

Ответ 22

Попробуйте использовать Database SetInitializer, который принадлежит System.Data.Entity;

В Global.asax

protected void Application_Start()
{
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<yourContext>());
}

Это создаст новую базу данных каждый раз, когда ваша модель будет изменена. Но ваша база данных будет пустой. Чтобы заполнить ее фиктивными данными, вы можете использовать Seeding. Что вы можете реализовать как:

Посев::

protected void Application_Start()
{
    Database.SetInitializer(new AddressBookInitializer());
                ----rest code---
}
public class AddressBookInitializer : DropCreateDatabaseIfModelChanges<AddressBook>
{
    protected override void Seed(AddressBook context)
    {
        context.yourmodel.Add(
        {

        });
        base.Seed(context);
    }

}

Ответ 23

Это странно, но все ответы здесь бесполезны для меня. Для меня работал инициализатор

MigrateDatabaseToLatestVersion

Здесь мое решение (я знаю, это может быть намного проще, но как я его использую):

class MyDbMigrateToLatest : MigrateDatabaseToLatestVersion<MyDbContext, Configuration>
{
}

public class MyDbContext: DbContext
{
    public MyDbContext() : base("DbName")
    {
        SetInitializer();
    }

    public MyDbContext(string connString) : base(connString)
    {
        SetInitializer();
    }

    private static void SetInitializer()
    {
        if (ConfigurationManager.AppSettings["RebuildDatabaseOnStart"] == "true")
            Database.SetInitializer(new MyDbInitializerForTesting());
        else
            Database.SetInitializer(new MyDbMigrateToLatest());
    }
}

public sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(MyDbContext context)
    {
        // Whatever
    }
}

MyDbInitializerForTesting просто наследует от DropCreateDatabaseAlways, поэтому в каком-то конкретном случае (тестирование) вся база данных перестраивается. В противном случае он перенесен в последнюю версию.

Мой источник: https://msdn.microsoft.com/en-us/data/jj591621.aspx#specific

Ответ 24

Хорошее предложение, однако, настолько точно во всех случаях. Я все понял. Пожалуйста, убедитесь, что вы запускаете "enable-migrations" с использованием окон PM в Visual Studio, а папка миграции будет добавлена ​​в ваш проект.

Убедитесь, что два файла класса С#, добавленные в папку, будут содержать все ваши модели и их соответствующие свойства.

Если у вас есть все, что построит решение, и publis для развертывания.

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

Ответ 25

У меня была та же проблема, когда мы использовали одну базу данных для двух приложений. Установка disableDatabaseInitialization="true" в разделе типа контекста работает для меня.

<entityFramework>
<providers>
  <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
<contexts>
  <context type="PreferencesContext, Preferences" disableDatabaseInitialization="true">
    <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[PreferencesContext, Preferences], [Migrations.Configuration, Preferences]], EntityFramework" />
  </context>
</contexts>

Подробнее https://msdn.microsoft.com/en-us/data/jj556606.aspx

Ответ 26

Создать собственный инициализатор контекста:

public class MyDbContextInitializer : MigrateDatabaseToLatestVersion<MyDbContext, Migrations.Configuration>
{
    public override void InitializeDatabase(MyDbContext context)
    {
        bool exists = context.Database.Exists();

        base.InitializeDatabase(context);

        if (!exists)
        {         
            MyDbSeed.Seed(context);
        }
    }       
}

Обратите внимание, что Migrations.Configuration - это класс, генерируемый командной строкой миграции в консоли диспетчера пакетов. Вам может потребоваться изменить внутренний на публичный модификатор класса Migrations.Configuration.

И зарегистрируйте его в своем OmModelCreating:

public partial class MyDbContext : DbContext
{

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<MyDbContext>(new MyDbContextInitializer());

        //other code for creating model
    }
}

Ответ 27

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

1) Откройте файл DbContext

2) Добавьте пространство имен, используя Microsoft.AspNet.Identity.EntityFramework;

3) public MyDbContext(): base ( "name = MyDbContext" )       {           Database.SetInitializer(новый DropCreateDatabaseAlways());       }