自数据库创build以来,支持<Database>上下文的模型已经发生了变化

错误消息:

“数据库创build后,支持”AddressBook“上下文的模型已经发生了变化,无论是手动删除/更新数据库,还是使用IDatabaseInitializer实例调用Database.SetInitializer,例如,RecreateDatabaseIfModelChanges策略会自动删除并重新创build数据库,可以select新的数据。“

我正在尝试使用代码优先function,以下是我写的:

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; } } 

和连接string:

 <?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> 

因此,数据库名称是“AddressBook”,当我尝试将联系人对象添加到上下文时发生错误。 我在这里错过了什么?

现在是:

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

在YourDbContext.cs文件中。

以下是由Jeff发布的关于实际发生的事情的一些信息:

对于那些看到这个例外的人:

“创build数据库后,支持”Production“上下文的模型已经发生了变化,无论是手动删除/更新数据库还是使用IDatabaseInitializer实例调用Database.SetInitializer

以下是正在发生的事情以及如何处理:

首次创build模型时,我们运行DatabaseInitializer来执行创build数据库(如果不存在)或添加种子数据。 默认的DatabaseInitializer尝试将使用模型所需的数据库模式与存储在使用数据库创build的EdmMetadata表(在Code First是创build数据库的那个时)中存储的模式的散列进行比较。 现有的数据库将不会有EdmMetadata表,所以不会有哈希…如果缺less该表,今天的实现将抛出。 因为它是默认版本,所以我们将在改变这种行为之前努力工作。 在此之前,现有数据库通常不需要任何数据库初始化程序,因此可以通过调用以下方式closures您的上下文types:

 Database.SetInitializer<YourDbContext>(null); 

杰夫

对于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); 

是的,Matt Frear是对的。 UPDATE -EDIT:注意到我同意其他人的意见,而不是将此代码添加到global.asax添加到您的DbContext类

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

正如其他人所说,这对于处理unit testing也是很好的。

目前我正在使用Entity Framework 6.1.3 / .NET 4.6.1

这个修复程序在CTP5之后不再有效。

你必须做Database.SetInitializer<YourContext>(null);

刚刚find答案,并想在这里更新。 只需要做到以下几点。

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

或者你可以在Application_Start()下的Global.asax.cs文件中join这一行:

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

确保将ProjectName.Path.Context更改为您的名称空间和上下文。 如果先使用代码,则只要对模式进行任何更改,都将删除并创build新的数据库。

只需在SQL Server Management Studio中运行followng sql命令:

 delete FROM [dbo].[__MigrationHistory] 

我花了很多天的时间来解决这个问题,分析了很多不同的post,并尝试了很多select, 最后修复。 这2个项目在我的解决scheme中使用EF代码第一次迁移:

  • 控制台应用程序“DataModel”,主要使用包含所有我的代码第一个实体,DbContext,Mirgations和通用存储库的程序集。 我已经包含到这个项目单独的空的本地数据库文件(在DataModel / App_Data文件夹),以便能够从包pipe理器控制台生成迁移。
  • WebApi,它引用DataModel项目并使用来自WebApi / App_Data文件夹的本地数据库文件,未包含在项目中

我得到这个错误,当请求WebApi …

我的环境:

  • Windows 8.1 x64
  • Visual Studio 2015 Professional与更新1
  • 我的所有项目都针对.NET Framework 4.6.1
  • 来自NuGet的EntityFramework 6.1.3

在这里,我收集了您应该注意的所有言论和必须满足的所有条件/要求,以避免提到的exception情况:

  1. 您应该只对解决scheme中的所有项目使用一个版本的EntityFramework Nuget包。
  2. 通过按顺序运行所有迁移脚本创build的数据库应该与您的目标数据库具有相同的结构/模式,并与实体模型相对应。 以下三件事情必须完全相符/反映/匹配:
    • 您的所有迁移脚本持续到最后
    • 当前代码第一个实体模型状态(DbContext,entities)
    • 目标数据库
  3. 目标数据库(mdf文件)应该更新/对应到上一个迁移脚本。 validation目标数据库中的“__MigrationHistory”表是否包含您拥有的所有迁移脚本的logging,这意味着所有迁移脚本已成功应用于该数据库。 我build议您使用Visual Studio生成正确的代码第一个实体和上下文,对应于您的数据库,项目 – >添加新项目 – > ADO.NET实体数据模型 – >代码优先从数据库: 当然,作为替代scheme,如果您没有数据库,则可以手动编写模型(代码优先实体和上下文),然后生成初始迁移和数据库。
  4. 连接string的名称例如启动项目的configuration文件(Web.config / App.config)中的MyConnectionString

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

    应该等于在DbContext的构造函数中传递的参数:

      public partial class MyDbContext : DbContext { public MyDbContext() : base("name=MyConnectionString"){} ... 
  5. 在使用软件包pipe理器控制台之前,请确保您使用正确的数据库进行更新或生成迁移,并将需要的项目设置为解决scheme的启动项目。 对于连接到数据库,它将使用该项目中的.config文件的连接string,该项目被设置为启动项目。
  6. 和主,这解决了我的问题:这是奇怪的,但在我的WebApi / bin文件夹DataModel.exe是旧的,没有刷新自上一次build立。 由于迁移embedded我的程序集DataModel.exe然后我的WebApi使用旧的镜像更新数据库。 我很困惑,为什么在WebApi中更新数据库后,它不对应于DataModel的最新迁移脚本。 以下代码自动创build(如果不存在)或更新到我的WebApi / App_Data文件夹中的最新迁移本地数据库。

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

    我试图干净和重build解决scheme,但它并没有帮助,比我完全从WebApi中删除bin和obj文件夹,从WebApi / App_Data删除数据库文件,内置,重新启动WebApi,请求它,创build正确的数据库 – 懒惰初始化上面的行),对应于最新的迁移和exception没有出现更多。 所以,这可能会解决您的问题:

    1. 从你的启动项目 (它生成/更新你的数据库) 手动删除bin,obj文件夹
    2. build立你的启动项目,或更好地清理和重build你的解决scheme。
    3. 通过启动项目重新创build数据库(将执行上面的行)或使用软件包pipe理器控制台“update-database”命令。
    4. 手动检查生成的db和__MirgationHistory是否对应最新的迁移脚本。

对于我来说,升级到4.3.1,我只是截断EdmMetaData表或直接删除它。

对于VB.NET开发人员:

将下面的行添加到方法Application_Start()的末尾的Glabal.asax.vb文件中

 Database.SetInitializer(Of ApplicationDbContext)(Nothing) 

将ApplicationDbContext更改为您的特定Db上下文。

我有这个问题,事实certificate,一个项目指向SQLExpress,但有问题的是指向LocalDb。 (在他们各自的web.config中)。 愚蠢的监督,但值得注意的情况下,以防其他人解决这个问题。

我有同样的问题 – 重新添加迁移和更新数据库不起作用,没有上述答案似乎是正确的。 然后,灵感打击了我 – 我使用多层(一个networking,一个数据和一个业务)。 数据层具有上下文和所有模型。 Web层从来没有抛出这个exception – 这是业务层(我设置为控制台应用程序进行testing和debugging)。 事实certificate,业务层没有使用正确的连接string来获取数据库并创build上下文。 所以我将连接string添加到业务层(和数据层)的应用程序configuration,中提琴的作品。 把这个放在这里可能会遇到同样的问题。

我使用Database.CompatibleWithModel方法(在EF5中可用)来testing模型和数据库是否匹配,然后再使用它。 我刚创build上下文后调用这个方法…

  // 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 } 

这意味着在没有被执行的上下文中有一些变化。 请首先运行Add-Migration来生成我们所做的更改(我们可能不知道的更改)然后运行Update-Database

当我们为两个应用程序使用一个数据库时,我遇到了同样的问题 在上下文types部分设置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

经过对这个主题的一些研究,我发现这个错误是基本上发生的,如果你有一个以前在本地sql server express上创build的db实例。 所以每当你有更新数据库,并尝试更新数据库/在数据库上运行一些代码,而无需运行使用Package Manager Console Update Database命令; 首先,你必须手动删除我们本地的sql express上的数据库。

此外,这个解决scheme工作,除非你有AutomaticMigrationsEnabled = false; 在您的configuration。

如果你使用版本控制系统(git,svn等),其他开发人员在生产阶段更新数据库对象,那么每当你更新代码库并运行应用程序时,这个错误就会增加。

如上所述,在代码库上有一些解决scheme。 但是,这对于一些情况是最实际的。

我也在阅读Pro ASP.NET MVC 4书,并遇到了同样的问题。 对我而言,在本书的“添加模型validation”部分进行修改后,我开始遇到问题。 我解决问题的方法是将我的数据库从本地数据库移到成熟的SQL Server 2012服务器。 (顺便说一下,我知道我很幸运,我可以切换到全面的版本,所以不要恨我;-)))必须有一些与数据库沟通是导致问题。

检查以下步骤

  1. Database.SetInitializer(NULL); – >在Global.asax.cs中

2。

  1. 您的上下文类名称应匹配与检查它

修改Global.asax.cs ,包括Application_Start事件:

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

此错误可能表示连接string的问题以及连接string名称是否与数据库上下文声明匹配。

我有这个错误,因为我错误地命名本地数据库(愚蠢的错误)和“DefaultConnection”的web.config中的连接string的名称不匹配的MyDbContext即

 public MyDbContext(): base("DefaultConnection") {} <connectionStrings> <add name="DefaultConnection" ... </connectionStrings> 

尝试使用属于使用System.Data.Entity的数据库SetInitializer;

在Global.asax中

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

这将在您的模型每次更改时创build新的数据库。但是您的数据库将是空的。为了填充虚拟数据,您可以使用“种子”。 你可以实现如下:

播种::

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

这很奇怪,但是这里的所有答案对我来说都是无用的。 对于我工作初始化

MigrateDatabaseToLatestVersion

这是我的解决scheme(我知道,它可以更简单,但是这是我的使用方式):

 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只是从DropCreateDatabaseAlwaysinheritance,所以在某些特定情况下(testing),整个数据库被重build。 否则,它会迁移到最新版本。

我的来源: https : //msdn.microsoft.com/en-us/data/jj591621.aspx#specific

不过,好的build议在所有情况下都非常准确。 我想出一个。 请确保在Visual Studio中使用PM窗口运行“enable-migrations”,并将Migration文件夹添加到您的项目中。

确保添加到文件夹中的两个c#类文件将包含所有模型及其各自的属性。

如果你有所有的构build解决scheme,并发布部署。

逻辑是,现有的元数据不能被覆盖,因为您的应用程序没有元数据来replace当前。 结果你得到这个错误“自从创build数据库以来,支持上下文的模型已经改变了”

以防万一有人和我一样。

我有数据库第一个EF和在同一时间使用asp.net身份

所以我有我的webconfig中的两个connectionStrings,并没有问题。 碰巧,我创build/运行脚本来手动生成我不应该的asp.net身份表。

所以DROP首先手动/从脚本创build的所有的asp.net身份表。

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

这些解决scheme都不适用于我们(除了完全禁用模式检查)。 最后,我们在我们的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> 

解决scheme是将汇编版本更正为我们实际部署的版本

 <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> 

在这里,我想分享另一种方法来防止上下文更改时模型支持的错误是:

1)打开你的DbContext文件

2)使用Microsoft.AspNet.Identity.EntityFramework添加命名空间;

3)public MyDbContext():base(“name = MyDbContext”){Database.SetInitializer(new DropCreateDatabaseAlways()); }