【问题标题】:Entity Framework with multiple models throws error stating "The model backing the <modelDbContext> context has changed..."具有多个模型的实体框架引发错误,指出“支持 <modelDbContext> 上下文的模型已更改...”
【发布时间】:2013-04-11 17:28:47
【问题描述】:

我尝试在同一个数据库中使用两个独立的不相关模型。以下是每个代码:

public class ImageDBContext : DbContext
{
    public ImageDBContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<ImageModel> Images { get; set; }

}

[Table("Images")]
public class ImageModel
{
    [Key]
    public int ID { get; set; }
    public string Type { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string FileName { get; set; }

    [NotMapped]
    public HttpPostedFileBase Attachment { get; set; }
}

这是另一个模型

public class TestimonialDBContext : DbContext
{
    public TestimonialDBContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<Testimonial> Testimonials { get; set; }
}

[Table("Testimonials")]
public class Testimonial
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

当我访问一个模型的视图时,效果很好。哪个模型无关紧要,但是当我转到另一个模型的视图时,我会收到此错误:

支持“ImageDBContext”上下文的模型自数据库创建以来已更改。考虑使用 Code First 迁移来更新数据库 (http://go.microsoft.com/fwlink/?LinkId=238269)。

在我看来,两个模型都在尝试使用同一张桌子?该表由第一个初始化的模型创建,但随后第二个模型尝试使用现有表而不是创建自己的表。

如何让两个模型在数据库中使用它们自己的表?

这是连接字符串:

 <add name="DefaultConnection" connectionString="Data Source=localhost\SQLEXPRESS;Initial Catalog=--------;User ID=-------;Password=---------" providerName="System.Data.SqlClient" />

更新:我已将以下代码添加到模型中,但仍然出现相同的错误。

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ImageModel>().ToTable("ImagesTable");
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Testimonial>().ToTable("TestimonialsTable");
    }

【问题讨论】:

  • 连接字符串出现问题,您可以重新创建模型并在 webconfig 中添加连接字符串设计时间可能会解决您的问题

标签: c# asp.net-mvc database entity-framework


【解决方案1】:

错误消息具有欺骗性 - 这不能/不应该通过“代码优先迁移”来解决。您有两个不同的 DbContext。如果它是同一个数据库,那么只需使用您添加了图像和推荐信的一个上下文。

按照您的操作方式,您基本上是在说有两个不同的数据库,它们使用相同的连接字符串,并且每个数据库都有一个表,ImagesTestimonials。因此,当您访问 Images 页面时,将使用一个表 Images 创建数据库。但是当您访问Testimonials 时,它会识别出数据库结构与Testimonials 表的模型不匹配并警告您。

像这样创建一个数据库上下文:

public class MyDBContext : DbContext
{
    public DbSet<ImageModel> Images { get; set; }
    public DbSet<Testimonial> Testimonials { get; set; }
}

当您需要访问数据库时,只需在您的控制器中创建此类的新实例。如果将连接字符串(在 web.config 中)命名为“MyDbContext”,则可以跳过需要调用 base("DefaultConnection") 的空构造函数。

【讨论】:

  • 现在完美运行。现在也有意义。感谢您的快速回复!
  • 嗯...实际上建议在多个 DbContexts 中拆分模型,特别是在处理大型数据库时)但我不确定是否可以使用 Model-First 方法...
【解决方案2】:

当模型被创建、迁移然后更新到 Db 中时 - EF/CF 会创建 __MigrationHistory - 它存储 DbContext 的确切 EDMX 模型、实体。

到目前为止,包括 EF 5 - 不支持多重迁移 表格。

理论上,您可以通过调整迁移脚本来同时运行两个迁移 - 并创建一个包含这两个集合的数据库,所以这不是问题。

但是当你制作两个模型/DbContext-s - 迁移表,Db 表布局和你的实体不匹配 - 对于同一个数据库...

从 EF 6 开始 - 您将获得对 multi-tenant migrations 的支持。即 EF6 将允许每个数据库有多个上下文。

有关更多信息和详细信息,请参阅我的这篇文章...
Migration not working as I wish... Asp.net EntityFramework

关闭迁移:

解决您遇到的问题的方法是删除 迁移。您可以简单地删除__MigrationHistory 表 (它在system tables 下),不要尝试进行迁移。

“侵入性”较小的方法(关闭迁移)是执行以下操作...

Database.SetInitializer<FirstContext>(null);
Database.SetInitializer<SecondContext>(null);  

(来自here

【讨论】:

  • 嗯... Julie Lerman(根据她在pluralsight.com 上的EF 课程)实际上建议将DbContext 拆分为多个派生上下文(使用一个BaseContext 和一个连接字符串)...跨度>
  • 顺便说一句,这太旧了...我不再推荐基本上下文,因为我们确实有更好的功能可以在新版本的 EF 中使用
  • @JulieLerman 顺便说一句。我知道它“太”老了 :) 但这并没有降低它的相关性(你的课程或 Q/A 尝试)——许多人由于各种原因仍然坚持使用旧版本(这只是从 6.0 开始,对,7还没有正式出,所以真的只有一个版本)
  • 我指的是我的建议,而不是问题所在。另外,从 EF6 开始,您可以对指向同一个数据库的多个 dbcontexts 使用迁移。我想在前面提到这一点,并指向我深入讨论此功能的某个地方,但在过去,我被指责通过指向我现有的内容而不是在 SO 线程中重新创建它来自私自利。
猜你喜欢
  • 2015-04-29
  • 2013-08-24
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
  • 2014-09-30
  • 2013-03-30
  • 1970-01-01
  • 2012-07-04
相关资源
最近更新 更多