错误信息:

“自数据库创建以来,支持‘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 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
    }
}

其他回答

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

以下是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

尝试使用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);
    }

}

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

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

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


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

实体框架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片段。