自创建数据库以来,支持<Database>上下文的模型已更改。

265

错误信息如下:

"自数据库创建以来,'AddressBook'上下文所支持的模型已更改。请手动删除/更新数据库,或使用IDatabaseInitializer实例调用Database.SetInitializer。例如,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>

所以,数据库名称是“AddressBook”,当我尝试将联系人对象添加到上下文时发生错误。这里有什么遗漏吗?


1
从您的数据库中删除 __MigrationHistory 表。 - Zahid Hasan
1
@ZahidHasan 绝对不要删除 __MigrationsHistory 表,除非您完全理解 __MigrationsHistory 的目的,并愿意手动协调代码和数据库之间的差异,并在生产环境中进行相同的更改。 - Aaron Queenan
27个回答

0
创建自定义的上下文初始化器:
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 是由 Package Manager Console 中的迁移命令生成的类。您可能需要将 Migrations.Configuration 类的 internal 修改为 public 修饰符。
然后在 OmModelCreating 中注册它:
public partial class MyDbContext : DbContext
{

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

        //other code for creating model
    }
}

0

修改 Global.asax.cs 文件,包括在 Application_Start 事件中添加以下内容:

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

5
个人认为,我会稍微更清晰地解释这个做什么。 - Casey
3
不,不,不,99%的时间我不想使用DropCreateDatabaseIfModelChanges! - Tom Stickel

0
我也在阅读《Pro ASP.NET MVC 4》这本书,遇到了你所遇到的同样的问题。对我来说,在按照书中“添加模型验证”一节中的指示进行更改后,我开始遇到这个问题。我解决这个问题的方法是将我的数据库从localdb移动到完整版的SQL Server 2012服务器上。(顺便说一句,我知道我很幸运能够切换到完整版,所以不要恨我。;-))))肯定是与与数据库通信有关的问题导致了这个问题。

你怎么知道它是与数据库的通信而不是例如元数据? - flup
2
抱歉回复晚了。事实证明这根本不是通信问题!重新创建数据库只是掩盖了问题,因为我再次遇到了同样的问题!一个名为__Migrationxxx(无法记住表的确切名称,因为我刚刚将其删除)的表由ef创建。只需删除它,你就可以解决问题了。 - J3Speaks
@MyJ3 所有人都在喋喋不休地说着这些该死的代码行。这就是我需要的!值得成为一个答案(可选情景)。 - Terrance00
@Terrance00 谢谢! - J3Speaks

0

请查看以下步骤

  1. Database.SetInitializer(null); -->在 Global.asax.cs 文件中

2.

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

0
经过对此主题的一些研究,我发现如果您之前在本地 SQL Server Express 上创建了 db 实例,则基本上会出现错误。因此,每当您更新 db 并尝试在没有使用“Package Manager Console”命令运行Update Database的情况下更新 db/运行一些代码时,首先必须手动删除我们本地 sql express 上的以前的 db。
此外,除非您的 Configuration 中有 AutomaticMigrationsEnabled = false;,否则此解决方案有效。
如果您使用版本控制系统(git、svn 等)并且其他开发人员在生产阶段更新 db 对象,则每当您更新代码库并运行应用程序时,就会出现此错误。
如上所述,代码库中有一些解决方案。然而,这是某些情况下最实用的解决方案。

0
尝试使用属于using System.Data.Entity的Database SetInitializer;
在Global.asax中。
protected void Application_Start()
{
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<yourContext>());
}

每当您的模型发生更改时,这将创建一个新的数据库。但是您的数据库将是空的。为了用虚拟数据填充它,您可以使用Seeding。您可以按照以下方式实现:

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

}

-3

这里我想分享另一种防止上下文更改时出现模型后备错误的方法:

1)打开您的DbContext文件

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

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


那会删除你的整个数据库。也许在开发阶段可以这样做,但是当那段代码意外地发布到生产环境并删除了所有数据时,没有人会对此感到满意。 - Aaron Queenan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接