2012-12-28 40 views
30

我有這個錯誤消息,每次運行應用程序時都會一直顯示。我使用的是實體Framework 5: Code FirstEF5獲取此錯誤消息:模型兼容性無法檢查,因爲數據庫不包含模型元數據

這裏的錯誤信息,

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 

當我創建了一個叫做發票實體此錯誤開始。下面是實體的全部代碼,

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。所以這個問題不會充滿代碼。

如果有詳細資料,我錯過了問題,請評論,所以我可以包括它。

回答

52

我發現的代碼通過改變

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

工作到

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

只需完成以下答案: 錯誤是因爲您在運行代碼後更改模型。你有兩種方法可以解決它: 1.你可以改變數據庫創建的邏輯,你在答案中是如何做到的; 2.或者你可以開始使用實體框架遷移,就像第二個答案; – MayogaX

+2

謝謝......它的工作。但它應該爲'ifmodelchanges'工作,因爲它以前一直在工作。 – Sami

+3

+1提示。但我認爲,我們隱藏了錯誤,而不是解決它。 * IfModelChanges *的問題是它依賴於* _MigrationHistory *表。我們通過**總是**躲避子彈創建數據庫,因此不需要歷史記錄。但是,一旦以* Always *運行,我認爲應該創建歷史表。它不在我的情況,雖然...我只看到表:* MSreplication_options *,* spt_fallback_db *,* spt_fallback_dev *,* spt_fallback_usg *和* spt_monitor *。 –

13

這可能與您的數據庫不包含_MigrationHistory表(可在Tables> System Tables中使用SQL Server Management Studio查看)相關。

不知道如何管理數據庫,但如果您仍在開發和使用EF遷移,快速解決方案是刪除數據庫並運行Update-Database,它將重新創建整個數據庫並添加_MigrationHistory表。

如果你想避免EF運行此檢查,你可以將它添加到您的DbContext類

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

我已經試過這個。 「IncludeMetadataConvention」在EF5上已經過時。如果你已經下載了這個項目,那麼我有很多的試驗和錯誤。無論如何,我非常感謝你的回答。 – Pedigree

+1

我試過這個建議,不幸的是它不工作。 – Akbari

+0

我想知道如何建議刪除數據庫。假設沒有奢侈品來刪除數據庫,並且假設爲了解決這個問題,你在這個階段刪除數據庫並且完成任務並且在3年後發生同樣的問題,並且在那個階段你沒有豪華刪除數據庫..然後會發生什麼? – Jogi

10

如果您試圖根據先前存在的山姆數據庫初始化上下文,也會發生這種情況e名稱,但它是用另一個代碼庫創建的。 這就是爲什麼從DropCreateDatabaseIfModelChanges更改爲DropCreateDatabaseAlways的原因,後一種配置會導致無論如何重新創建數據庫,從而繞過可能導致此問題的任何類型的數據庫版本控制。

+2

我也有這種情況。我將它改爲Always,運行它,然後將其更改回IfModelChanges。現在工作正常。 – mcolegro

+0

即使使用相同的代碼優先模型,它也會發生。在運行兩個應用程序時遇到了這個問題,其中一個應用程序沒有* db_owner *角色並拋出異常(即使_MigrationHistory存在,DB使用EF ** **代碼庫創建了另一個應用程序)。 – wondra

+0

我在App_Data文件夾中使用localdb,mdf文件 – Kiquenet

-1
CreateDatabaseIfNotExists<ApplicationDbContext>(); 
+4

通常情況下,如果答案包含解釋代碼意圖做什麼的解釋,以及爲什麼解決問題而不介紹其他問題,答案會更有幫助。 –

9

如果和我一樣,這是由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(); 
    } 
} 

這將內置的身份識別模型起步時經常發生。一旦你得到他們的工作,你可以刪除該行,以保持完好,但保留功能。但是,如果您的模型發生變化,您的數據庫將不得不配置爲匹配..無論如何,您在數據庫優先開發中所做的一切!

+0

我有這個確切的問題。感謝您的解決方案。 – ajmena

+0

謝謝!這應該至少也是這個問題的正確答案。我遇到了同樣的情況:從代碼第一個變爲db第一個中間項目 –

0

當我添加
ContextKey = "MyProject.Repository.Common.DbContextA";

到Configuration.cs我得到這個錯誤。刪除該行後,它可以正常工作。

0

我嘗試了3個步驟以下。 它爲我..運行 1.啓用的遷移 2.更新數據庫-verbose 3.附加遷移initialmigrations -ignorechanges

注意在包管理器控制檯下面的命令:是我已經創建了我的情況(使用代碼優先的方法(使用共享的數據庫上下文庫)我試圖在另一個應用程序和另一個數據庫中使用該庫我手動將第一個數據庫同步到第二..這就是爲什麼我遇到了這個問題

0

我知道我遲到了,但我剛剛遇到同樣的錯誤,並且我的數據庫已經有一個遷移歷史記錄表

該錯誤也可能表明歷史記錄表中的上下文關鍵字不正確。如果將數據庫上下文類移動到另一個名稱空間,就像我在重構時那樣,可能會發生這種情況。

MigrationHistory表中的ContextKey值更新爲數據庫上下文的新名稱空間,修復了我的問題

該解決方案不要求您丟棄數據庫內容,因此可能優於DropCreateDatabaseAlways解決方案。

相關問題