EF5 Getting this error message: Model compatibilit

2019-01-10 13:17发布

问题:

I have this error message that keeps on displaying every time I run the application. I'm using Entity Framework 5: Code First

Here's the error message,

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

This error started when I created an entity called invoice. Here's the full code of the entity,

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

In order to replicate the application, I have included the project file which is available for download. And so this question will not be full of code.

If there are details that I've missed in the question, please comment so I can include it.

回答1:

I found the code working by changing

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

into

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


回答2:

This is probably related to your database not containing the _MigrationHistory table (which can be viewed using SQL Server Management Studio in Tables > System Tables).

Not sure how you are managing the database, but if you are still in development and using EF Migrations a quick solution is to delete the database and run Update-Database which will recreate the entire database and add the _MigrationHistory table.

If you want to avoid EF running this check you can add this to your DbContext class

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


回答3:

If, like me, this is caused by starting with Code First and changing to Database First development mid-project.. this is all caused by one simple line. If you need to keep your database and its data comment out the following line:

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

from this section of your Model.

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

This will happen often in when starting out with the built in identity models. Once you get them working, you can remove that line to keep it intact yet retain the functionality. If your model changes, however, your database will have to be configured to match.. something you are doing in Database First development anyway!



回答4:

This can also happen if you are trying to initialise the context against a previously existing database of the same name but that was created with another codebase. This is why changing from DropCreateDatabaseIfModelChanges to DropCreateDatabaseAlways works, the latter configuration causes the database to be recreated no matter what, bypassing any sort of database versioning that might be causing this issue.



回答5:

I know I'm late to the party, but I just came across the same error, and my database already had a migration history table.

The error might also indicate an incorrect context key in the history table. This may happen if you move the database context class to another namespace, like I did while refactoring.

Updating the ContextKey value in the MigrationHistory table to the new namespace of the database context fixed the issue for me.

This solution does not require you to discard the database contents so may be preferred over the DropCreateDatabaseAlways solution.



回答6:

I got this error when I add
ContextKey = "MyProject.Repository.Common.DbContextA";

to Configuration.cs. After remove that line, it works.



回答7:

I tried below 3 steps . It works for me.. Run the following commands in package manager console 1. enable-migrations 2. update-database -verbose 3. add-migration initialmigrations -ignorechanges

NOTE: My scenario is I already created the db/tables (using code first approach (using a shared DB context library). I trying to use the library in another application and another database. I manually synched the first db into second.. thats why i encountered this problem.



回答8:

CreateDatabaseIfNotExists<ApplicationDbContext>();