【问题标题】:EF5 Getting this error message: Model compatibility cannot be checked because the database does not contain model metadataEF5 收到此错误消息:无法检查模型兼容性,因为数据库不包含模型元数据
【发布时间】:2012-12-28 04:06:08
【问题描述】:

我每次运行应用程序时都会显示此错误消息。我正在使用实体Framework 5: Code First

这是错误信息,

System.NotSupportedException: Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations.
   at System.Data.Entity.Internal.ModelCompatibilityChecker.CompatibleWithModel(InternalContext internalContext, ModelHashCalculator modelHashCalculator, Boolean throwIfNoMetadata)
   at System.Data.Entity.Internal.InternalContext.CompatibleWithModel(Boolean throwIfNoMetadata)
   at System.Data.Entity.Database.CompatibleWithModel(Boolean throwIfNoMetadata)
   at System.Data.Entity.DropCreateDatabaseIfModelChanges`1.InitializeDatabase(TContext context)
   at System.Data.Entity.Database.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c)
   at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6()
   at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
   at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
   at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
   at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   at System.Data.Entity.Internal.InternalContext.Initialize()
   at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
   at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
   at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
   at System.Data.Entity.DbSet`1.Add(TEntity entity)
   at LaundryService_DEMO.frmMain.btnCreate_Click(Object sender, EventArgs e) in d:\MyDocs\Visual Studio 2012\Projects\LaundryService_DEMO\LaundryService_DEMO\frmMain.cs:line 39

当我创建一个名为 invoice 的实体时,这个错误就开始了。这是实体的完整代码,

public class Invoice
{
    public string InvoiceID { get; set; }
    public string CustomerID { get; set; }
    public string UserID { get; set; }
    public decimal TotalAmount { get; set; }
    public DateTime TransactionDate { get; set; }
    public DateTime PaymentDate { get; set; }

    public Customer CustomerField { get; set; }
    public SystemUser SystemUserField { get; set; }
}

public class InvoiceMap : EntityTypeConfiguration<Invoice>
{
    public InvoiceMap()
    {
        // Primary Key
        this.HasKey(x => x.InvoiceID);

        // Property(ies) and Mapping(s)
        this.ToTable("Invoice");

        this.Property(x => x.InvoiceID)
            .IsRequired()
            .HasMaxLength(15)
            .HasColumnName("InvoiceID")
            .HasColumnType("nVarchar");

        this.Property(x => x.CustomerID)
            .IsRequired()
            .HasMaxLength(15)
            .HasColumnName("CustomerID")
            .HasColumnType("nVarchar");

        this.Property(x => x.UserID)
            .IsRequired()
            .HasMaxLength(15)
            .HasColumnName("UserID")
            .HasColumnType("nVarchar");

        this.Property(x => x.TotalAmount)
            .IsRequired()
            .HasColumnName("TotalAmount")
            .HasColumnType("decimal");

        this.Property(x => x.TransactionDate)
            .IsRequired()
            .HasColumnName("TransactionDate")
            .HasColumnType("datetime");

        this.Property(x => x.PaymentDate)
            .IsOptional()
            .HasColumnName("PaymentDate")
            .HasColumnType("datetime");

        // Relationship
        this.HasRequired(x => x.CustomerField)
            .WithMany(x => x.InvoiceCollection)
            .HasForeignKey(y => y.CustomerID);

        this.HasRequired(x => x.SystemUserField)
            .WithMany(x => x.InvoiceCollection)
            .HasForeignKey(y => y.UserID);
    }
}

为了复制应用程序,我包含了项目文件available for download。所以这个问题不会充满代码。

如果我在问题中遗漏了一些细节,请发表评论,以便我将其包括在内。

【问题讨论】:

    标签: c# .net entity-framework entity-framework-5


    【解决方案1】:

    我发现通过更改代码可以工作

    static LaundryShopContext()
    {
      Database.SetInitializer<LaundryShopContext>(
        new DropCreateDatabaseIfModelChanges<LaundryShopContext>());
    }
    

    进入

    static LaundryShopContext()
    {
      Database.SetInitializer<LaundryShopContext>(
        new DropCreateDatabaseAlways<LaundryShopContext>());
    }
    

    【讨论】:

    • 只需完成答案:错误是因为您在运行代码后更改了模型。您有两种方法可以修复它: 1. 您可以更改数据库创建的逻辑,以及您在答案中是如何做到的; 2.或者你可以开始使用Entity Framework Migrations,就像第二个答案一样;
    • 谢谢...它成功了。但它应该对我有用 ifmodelchanges 因为它以前一直在工作。
    • +1 以获得很好的提示。不过,我认为我们隐藏了错误,而不是解决它。 IfModelChanges 的问题在于它依赖于 _MigrationHistory 表。我们通过总是创建数据库来躲避子弹,因此不需要历史记录。但是,在我看来,一旦使用 Always 运行,就应该创建历史记录表。但在我的情况下不是...我只看到表:MSreplication_optionsspt_fallback_dbspt_fallback_devspt_fallback_usg i> 和 spt_monitor.
    • 这些数据库初始化是非常糟糕的解决方案......它可以删除数据......迁移应该是一个更好的解决方案,至少更安全。
    • @Pedigree,当您将整个方案从 DropCreateDatabaseIfModelChanges&lt;LaundryShopContext&gt;() 更改为 DropCreateDatabaseAlways&lt;LaundryShopContext&gt;() 时,如何将其标记为答案。两种方案的含义完全不同。您如何通过更改整个场景来将其标记为 aswer。和@KonradViltersten 当Always 创建新数据库时,您为什么希望它创建_Migration(History) 文件夹?我的意思是当一个新的数据库已经被创建时,你为什么需要知道历史?
    【解决方案2】:

    这可能与您的数据库不包含 _MigrationHistory 表有关(可以使用 SQL Server Management Studio 在表 > 系统表中查看)。

    不确定您是如何管理数据库的,但如果您仍处于开发阶段并使用 EF 迁移,一个快速的解决方案是删除数据库并运行 Update-Database,这将重新创建整个数据库并添加 _MigrationHistory 表。

    如果您想避免 EF 运行此检查,可以将其添加到您的 DbContext 类中

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
    }
    

    【讨论】:

    • 这个我已经试过了。 IncludeMetadataConvention 在 EF5 上已经过时。如果您已经下载了该项目,我会在那里进行大量试验和错误。无论如何,我非常感谢您的回答。
    • 我已经尝试过这个建议,很遗憾它不起作用。
    • 我想知道您如何建议删除数据库。假设没有删除数据库的余地,假设为了解决这个问题,你在这个阶段删除了数据库并完成工作,同样的问题在 3 年后发生,在那个阶段你没有删除数据库的奢侈......然后会发生什么?
    • 另一个问题可能是,假设你有一个数据库优先的方法来访问同一个数据库中的几个表,你有 codefirst 方法。所以为了codefirst解决方案而删除数据库意味着删除edmx上下文类和实体???这不是解决办法。
    • 我使用localdb,mdf文件在App_Data文件夹中
    【解决方案3】:

    如果像我一样,这是从 Code First 开始并在项目中更改为 Database First 开发的.. 这都是由一个简单的行引起的。如果您需要保留数据库及其数据,请注释掉以下行:

    Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
    

    来自模型的这一部分。

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }
        static ApplicationDbContext()
        {
            // Set the database intializer which is run once during application start
            // This seeds the database with admin user credentials and admin role
            //   Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
        }
    
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }
    

    在开始使用内置身份模型时,经常会发生这种情况。一旦你让它们工作,你可以删除那条线以保持它的完整性,同时保留功能。但是,如果您的模型发生更改,则必须将您的数据库配置为匹配……无论如何,您在 Database First 开发中正在做的事情!

    【讨论】:

    • 我遇到了这个确切的问题。感谢您的解决方案。
    • 谢谢!这至少应该也是这个问题的正确答案。我有同样的情况:从代码优先更改为 db first mid project
    【解决方案4】:

    如果您尝试针对以前存在的同名数据库初始化上下文,但该数据库是使用另一个代码库创建的,也会发生这种情况。 这就是为什么从 DropCreateDatabaseIfModelChanges 更改为 DropCreateDatabaseAlways 有效的原因,后一种配置会导致无论如何都要重新创建数据库,从而绕过可能导致此问题的任何类型的数据库版本控制。

    【讨论】:

    • 我也遇到过这种情况。我将其更改为 Always,运行它,然后将其更改回 IfModelChanges。现在工作正常。
    • 即使使用相同的代码优先模型也会发生这种情况。运行两个应用程序时遇到此问题,其中一个没有 db_owner 角色并引发异常(即使存在 _MigrationHistory,DB 是使用 EF same创建的另一个应用程序> 代码库)。
    • 我在 App_Data 文件夹中使用 localdb, mdf 文件
    【解决方案5】:

    我知道我迟到了,但我刚刚遇到了同样的错误,我的数据库已经有一个迁移历史表。

    该错误还可能表明历史表中的上下文键不正确。如果您将数据库上下文类移动到另一个命名空间,这可能会发生,就像我在重构时所做的那样。

    MigrationHistory 表中的ContextKey 值更新为数据库上下文的新命名空间解决了我的问题

    此解决方案不需要您丢弃数据库内容,因此可能比DropCreateDatabaseAlways 解决方案更受欢迎。

    【讨论】:

    • 祝福你!这也发生在我身上,因为我将我的数据代码从我的域项目中移到了它自己的具有不同命名空间的项目中!再次感谢。
    【解决方案6】:

    添加时出现此错误
    ContextKey = "MyProject.Repository.Common.DbContextA";

    到 Configuration.cs。删除该行后,它就可以工作了。

    【讨论】:

      【解决方案7】:

      我尝试了以下 3 个步骤。 它对我有用.. 在包管理器控制台中运行以下命令 1. 启用迁移 2. 更新数据库 -verbose 3. add-migration initialmigrations -ignorechanges

      注意:我的场景是我已经创建了数据库/表(使用代码优先方法(使用共享数据库上下文库)。我尝试在另一个应用程序和另一个数据库中使用该库。我手动将第一个数据库同步到第二个数据库..这就是我遇到这个问题的原因。

      【讨论】:

        【解决方案8】:
        CreateDatabaseIfNotExists<ApplicationDbContext>();
        

        【讨论】:

        • 一般来说,如果答案包含对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。
        猜你喜欢
        • 2014-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多