错误信息:

“自数据库创建以来,支持‘AddressBook’上下文的模型已经发生了变化。手动删除/更新数据库,或者调用database。带有IDatabaseInitializer实例的SetInitializer。例如,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>

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


刚刚找到答案,想在这里更新。只需要做以下事情。

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

此修复在CTP5之后不再有效。

你必须执行database。setinitializer <YourContext>(null);


现在是:

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

在你的YourDbContext.cs文件中。


以下是Jeff在Scott Gu的博客上发布的一些信息:

For those who are seeing this exception: "The model backing the 'Production' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance." Here is what is going on and what to do about it: When a model is first created, we run a DatabaseInitializer to do things like create the database if it's not there or add seed data. The default DatabaseInitializer tries to compare the database schema needed to use the model with a hash of the schema stored in an EdmMetadata table that is created with a database (when Code First is the one creating the database). Existing databases won’t have the EdmMetadata table and so won’t have the hash…and the implementation today will throw if that table is missing. We'll work on changing this behavior before we ship the fial version since it is the default. Until then, existing databases do not generally need any database initializer so it can be turned off for your context type by calling: Database.SetInitializer<YourDbContext>(null); Jeff


对我来说,在升级到4.3.1之后,我只是截断了EdmMetaData表,或者直接删除它。


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

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

确保将ProjectName.Path.Context更改为您的名称空间和上下文。如果先使用代码,那么每当对模式进行任何更改时,都会删除并创建一个新数据库。


在对这个主题进行了一些研究之后,我发现如果您之前在本地sql server express上创建了一个db实例,就会发生这个错误。因此,无论何时你在db上有更新,并试图更新db/在db上运行一些代码,而不使用包管理器控制台运行更新数据库命令;首先,您必须手动删除本地SQL express上以前的db。

此外,除非你的配置中有AutomaticMigrationsEnabled = false;,否则这个解决方案是有效的。

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

如上所述,在代码基础上有一些解决方案。然而,在某些情况下,这是最实用的方法。


I am reading the Pro ASP.NET MVC 4 book as well, and ran into the same problem you were having. For me, I started having the problem after making the changes prescribed in the 'Adding Model Validation' section of the book. The way I resolved the problem is by moving my database from the localdb to the full-blown SQL Server 2012 server. (BTW, I know that I am lucky I could switch to the full-blown version, so don't hate me. ;-))) There must be something with the communication to the db that is causing the problem.


实体框架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);

是的,马特·弗雷尔是对的。更新-编辑:警告是我同意其他人的观点,而不是将此代码添加到全局。asax添加到你的DbContext类

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

正如其他人提到的,这也有利于处理单元测试。

目前,我正在使用实体框架6.1.3 /.net 4.6.1

在不久的将来,我将回来提供一个CORE片段。


我有这个问题,原来是一个项目指向SQLExpress,但有问题的是指向LocalDb。(在它们各自的web.config中)。愚蠢的疏忽,但值得注意的是,如果其他人正在排除这个问题。


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

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

检查以下步骤

Database.SetInitializer(空);——> Global.asax.cs

2.

你的Context类名应该与之匹配 检查它


我使用数据库。CompatibleWithModel方法(在EF5中可用)在我使用它之前测试模型和DB是否匹配。我在创建上下文之后调用这个方法…

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

        }

此错误可能表明连接字符串有问题,以及连接字符串名称是否与数据库上下文声明匹配。

我有这个错误,因为我错误地命名了本地数据库(愚蠢的错误)和web中的连接字符串的名称。“DefaultConnection”的配置与MyDbContext不匹配。

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


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

VB。NET开发人员:

在方法Application_Start()的末尾向Glabal.asax.vb文件添加以下行

Database.SetInitializer(Of ApplicationDbContext)(Nothing)

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


尝试使用Database SetInitializer,它属于using System.Data.Entity;

在Global.asax

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

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

播种::

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

以下是我的解决方案(我知道,它可以简单得多,但这就是我使用它的方式):

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


好建议,但并非在所有情况下都如此准确。我算出一个。 请确保您在Visual Studio中使用PM窗口运行“enable-migrations”,迁移文件夹将添加到您的项目中。

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

如果您拥有所有这些,就构建解决方案,并发布部署。

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


这意味着上下文上的一些更改还没有执行。 请先运行Add-Migration来生成我们所做的更改(我们可能没有意识到的更改) 然后运行Update-Database


在这里,我想分享另一种防止上下文改变时模型备份错误的方法:

1)打开DbContext文件

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

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


我花了很多天来解决这个问题,分析了很多不同的帖子,尝试了很多选择,最终解决了这个问题。 这2个项目在我的解决方案使用EF代码第一次迁移:

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

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

我的环境:

Windows 8.1 x64 Visual Studio 2015 Professional with Update 1 我所有的项目都针对。net Framework 4.6.1 EntityFramework 6.1.3 from NuGet

在这里,我收集了所有你应该注意的事项和所有必须满足的条件/要求,以避免提到的例外:

You should use only one version of EntityFramework Nuget package for all projects in your solution. Database, created by running sequentially all migration scripts should have the same structure/schema as you target database and correspond to entity model. Following 3 things must exactly correspond/reflect/match each other: Your all migration script up to last Current code first entity model state (DbContext, entities) Target database Target database (mdf file) should be updated/correspond up to last migration script. Verify that "__MigrationHistory" table in your target database contains records for all migration scripts that you have, it means that all migration scripts was successfully applied to that database. I recommend you to use Visual Studio for generation correct code first entities and context that corresponds to your database, Project -> Add New Item -> ADO.NET Entity Data Model -> Code First from database: Of course, as an alternative, if you have no database you can write manually model (code first entities and context) and then generate initial migration and database. Name of connection string e.g. MyConnectionString in config file of startup project (Web.config/App.config): <configuration> <connectionStrings> <add name="MyConnectionString" connectionString="..."> </connectionStrings> <configuration> should be equal to parameter passed in constructor of your DbContext: public partial class MyDbContext : DbContext { public MyDbContext() : base("name=MyConnectionString"){} ... Before using Package Manager Console, make sure that you are using correct database for update or generate migration and needed project is set as startup project of solution. For connect to database it will use connection string from that .config file, which in project, that is set as startup project. And the main, which fixed my issue: It is weird, but in my WebApi/bin folder DataModel.exe was old, not refreshed since last build. Since migrations was embedded in my assembly DataModel.exe then my WebApi updated database using old mirgations. I was confused why after updating database in WebApi it not corresponds to latest migration script from DataModel. Following code automatically creates(if not exists) or updates to latest migration local database in my WebApi/App_Data folder. public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { Database.SetInitializer(new MigrateDatabaseToLatestVersion<ODS_DbContext, Configuration>()); ... I tried clean and rebuild solution but it did not help, than I completely removed bin and obj folders from WebApi, deleted database files from WebApi/App_Data, built, restarted WebApi, made request to it, it created correct database - lazy initialization (using lines above), which corresponds to latest migration and exception didn't appear more. So, this may fix your problem: remove manually bin, obj folders from your startup project (which generates/updates your database) build your startup project or better clean and rebuild all you solution. recreate database by starting project (will execute lines above) or use Package Manager Console "update-database" command. manually check whether generated db and __MirgationHistory corresponds to latest migration script.


当我们为两个应用程序使用一个数据库时,我遇到了同样的问题。设置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 Management Studio中执行如下sql命令:

delete FROM [dbo].[__MigrationHistory]

I had the same issue - re-adding the migration and updating the database didn't work and none of the answers above seemed right. Then inspiration hit me - I'm using multiple tiers (one web, one data, and one business). The data layer has the context and all the models. The web layer never threw this exception - it was the business layer (which I set as console application for testing and debugging). Turns out the business layer wasn't using the right connection string to get the db and make the context. So I added the connection string to the app config of the business layer (and the data layer) and viola it works. Putting this here for others who may encounter the same issue.


以防有人遇到和我一样的情况。

我有数据库首先EF,同时使用asp.net身份

所以我在我的webconfig中有两个connectionStrings,这没有问题。碰巧我创建/运行脚本手动生成asp.net标识表,我不应该这样做。

所以首先DROP所有的asp.net标识表,由你手工创建/从脚本。

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

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

创建自定义上下文初始化项:

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

注意迁移。Configuration是Package Manager Console中由迁移命令行生成的类。您可能需要将迁移的内部修饰符更改为公共修饰符。配置类。

并从您的OmModelCreating注册它:

public partial class MyDbContext : DbContext
{

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

        //other code for creating model
    }
}