Модель, поддерживающая контекст <Database>, изменилась с момента создания базы данных - PullRequest
239 голосов
/ 30 августа 2010

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

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

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

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>

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

Ответы [ 27 ]

378 голосов
/ 26 мая 2011

Теперь это:

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

в вашем файле YourDbContext.cs.

130 голосов
/ 02 июня 2011

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

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

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

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

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

Database.SetInitializer<YourDbContext>(null);

Jeff

37 голосов
/ 21 февраля 2013

Для Entity Framework 5.0.0.0 - 6.1.3

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

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
}

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

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

30 голосов
/ 28 февраля 2011

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

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

23 голосов
/ 21 июня 2016

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

delete FROM [dbo].[__MigrationHistory]
19 голосов
/ 30 августа 2010

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

public class AddressBook: DbContext
{
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
    modelBuilder.IncludeMetadataInDatabase = false;
   }
}
16 голосов
/ 01 декабря 2012

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

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

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

8 голосов
/ 14 января 2016

Я потратил много дней на решение этой проблемы, проанализировал множество различных постов и перепробовал множество вариантов, и окончательно исправил. Это 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

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

  1. Для всех проектов в вашем решении следует использовать только одну версию пакета EntityFramework Nuget.
  2. База данных, созданная при последовательном запуске всех сценариев миграции, должна иметь ту же структуру / схему, что и целевая база данных, и соответствоватьмодель объекта.Следующие 3 вещи должны точно соответствовать / отражать / соответствовать друг другу:
    • Ваш весь сценарий миграции до последнего
    • Текущее состояние первой модели сущности кода (DbContext, entity)
    • Targetбаза данных
  3. Целевая база данных (файл mdf) должна быть обновлена ​​/ соответствовать последнему сценарию миграции.Убедитесь, что таблица «__MigrationHistory» в целевой базе данных содержит записи для всех имеющихся у вас сценариев миграции, это означает, что все сценарии миграции были успешно применены к этой базе данных.Я рекомендую вам использовать Visual Studio для генерации правильных кодовых первых сущностей и контекста, соответствующего вашей базе данных, Project -> Add New Item -> ADO.NET Entity Data Model -> Code First из базы данных: Конечно, в качестве альтернативы, если у вас нет базы данных, вы можете написать модель вручную (сначала кодировать сущности и контекст), а затем создать начальную миграцию и базу данных.
  4. Имя строки подключения, например, MyConnectionString в конфигурационном файле запускаемого проекта (Web.config / App.config):

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

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

     public partial class MyDbContext : DbContext
     {
        public MyDbContext()
           : base("name=MyConnectionString"){}
        ...
    
  5. Перед использованием Консоль диспетчера пакетов убедитесь, что вы используете правильную базу данных для обновления или создания миграции, и необходим необходимый проект.в качестве запускается проект решения. Для подключения к базе данных будет использоваться строка подключения из того файла .config, который в проекте установлен как запускаемый проект.
  6. И главное, что решило мою проблему: Это странно, но в моей папке WebApi / bin DataModel.exe был старым, не обновлялся с момента последней сборки.Так как миграции были встроены в мою сборку DataModel.exe, тогда моя WebApi обновила базу данных, используя старые зеркала.Меня смутило, почему после обновления базы данных в WebApi она не соответствует последнему скрипту миграции из 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, сделал запрос к нему,он создал правильную базу данных - ленивая инициализация (используя строки выше), которая соответствует последней миграции, и исключение больше не появлялось. Итак, это может решить вашу проблему:

    1. удалить вручную папки bin, obj из вашего запуска проекта (который генерирует / обновляет вашу базу данных)
    2. создайте свой стартовый проект или лучше очистите и перестройте все, что вам нужно решение.
    3. создайте базу данных заново, запустив проект (выполнит строки выше) или воспользуйтесь командой «Обновить базу данных» консоли диспетчера пакетов.
    4. вручную проверить, соответствуют ли сгенерированные db и __MirgationHistory последнему сценарию миграции.
5 голосов
/ 04 мая 2012

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

3 голосов
/ 20 сентября 2014

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

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

Database.SetInitializer(Of ApplicationDbContext)(Nothing)

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

...