locked
Need help with the "model backing the context has changed since the database was created" error RRS feed

  • Question

  • I'm working on learning how to use logging with EF 6. I started a new console project to open a table in one of our developer databases. I'm using VS 2017. I included EF 6.1.3 using the Package Manager Console. The I created a class that models the table in the database and created a class derived from DbContext. This is what I believe is called a code first with existing database. (Might have left out some step.)

    First problem I was having is it wasn't returning any data. (Although the EF logging was working OK.) After several attempts have fixing it I took a closer look at the output from the EF logger and saw my problem. It was trying to look at the dbo schema for the table. The table, named Grievance, isn't in the dbo schema, it is in a schema named LRAT.

    So looking more online I discovered how to handle this. I had to overwrite the OnModelCreating method in the DbContext derived table. So here's what I've got so far:

    using System.Data.Entity;
    
    namespace TestEFLogging.Model
    {
        public class GrievanceContext : DbContext
        {
            public DbSet<Grievance> Grievances { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Grievance>().ToTable("Grievance", schemaName: "LRAT");
                base.OnModelCreating(modelBuilder);
            }
        }
    }
    

    Now I thought I'd be in like Flynn, but no. Now I'm getting this error:

    "The model backing the 'GrievanceContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269)."

    So next I looked up that error and I find lots of search results, most saying things like other search results are for older versions of EF, don't trust them, yada, yada, yada.

    So how do I fix this problem? The database did not change as the error suggests. I wasn't aware of the fact that if the table isn't in the dbo schema that you have to specify that in the derived DbContext code.

    (Just to make it clear, in the code above Grievance is the name of the model class I made. I've never used the DbModelBuilder class before, but I assumed that naming the table name the same thing as the model name, which is the same thing as the name of the table in the database, is OK.)


    Rod

    Thursday, April 6, 2017 6:12 PM

Answers

  • OK, after playing with this more I finally came up with the solution. It took a couple of things.

    First, as you said David I did put in the code you gave (Database.SetInitializer) in the constructor of my DbContext derived class. However, in a way it didn't matter. I'll get to that later.

    Next I found that I was using the wrong providerName in the connection string. I had been using System.Data.EntityClient. I needed to change that to System.Data.SqlClient. The first is for the EF Designer, with the .EDMX file. Since I wasn't using that at all, I needed to specify the provider for ADO.NET.

    (As an aside, I don't quite understand the relationship between ADO.NET and EF, when it comes to using code first. Looks like if you're using code first, you must use the ADO.NET provider, at least if SQL Server is involved.)

    Next I found that I was using the wrong name for the database connection! I had been using Grievance, but my DbContext derived class is named GrievanceContext. I had to change the database connection name to GrievanceContext.

    Finally it worked. I tried commented out the Database.SetInitializer call in the constructor. I found that it still worked. But I had put into place some additional debugging code to see what was going on and that revealed that also my program worked without the call to Database.SetInitializer in the class' constructor, I was getting the following failures:

    "Failed in 7 ms with error: Invalid object name 'dbo.__MigrationHistory'."

    So it was trying to execute a migration, but since our database doesn't include any table named __MigrationHistory, regardless of what schema its in, that just ran over and over again until it gave up and went on. So including the call to Database.SetInitializer in the constructor actually made it run without it's needlessly trying to migrate the database, thus running faster.

    I hope this helps someone else.


    Rod

    Thursday, April 6, 2017 9:11 PM

All replies

  • Not sure.  Did you try setting 

    Database.SetInitializer<GrievanceContext>(null);

    at the begging of your program?  This will turn off all the initialization, disabling the migrations as well.

    David


    Microsoft Technology Center - Dallas
    My blog

    Thursday, April 6, 2017 6:43 PM
  • David, where do I put that? In the constructor for the GrievanceContext class? 

    Rod

    Thursday, April 6, 2017 7:06 PM
  • OK, after playing with this more I finally came up with the solution. It took a couple of things.

    First, as you said David I did put in the code you gave (Database.SetInitializer) in the constructor of my DbContext derived class. However, in a way it didn't matter. I'll get to that later.

    Next I found that I was using the wrong providerName in the connection string. I had been using System.Data.EntityClient. I needed to change that to System.Data.SqlClient. The first is for the EF Designer, with the .EDMX file. Since I wasn't using that at all, I needed to specify the provider for ADO.NET.

    (As an aside, I don't quite understand the relationship between ADO.NET and EF, when it comes to using code first. Looks like if you're using code first, you must use the ADO.NET provider, at least if SQL Server is involved.)

    Next I found that I was using the wrong name for the database connection! I had been using Grievance, but my DbContext derived class is named GrievanceContext. I had to change the database connection name to GrievanceContext.

    Finally it worked. I tried commented out the Database.SetInitializer call in the constructor. I found that it still worked. But I had put into place some additional debugging code to see what was going on and that revealed that also my program worked without the call to Database.SetInitializer in the class' constructor, I was getting the following failures:

    "Failed in 7 ms with error: Invalid object name 'dbo.__MigrationHistory'."

    So it was trying to execute a migration, but since our database doesn't include any table named __MigrationHistory, regardless of what schema its in, that just ran over and over again until it gave up and went on. So including the call to Database.SetInitializer in the constructor actually made it run without it's needlessly trying to migrate the database, thus running faster.

    I hope this helps someone else.


    Rod

    Thursday, April 6, 2017 9:11 PM
  • Hi Rod at Work,

    I am glad to know that you resolve the issue and share the solution to us, please mark it as answer, it will be beneficial to other communities who have the similar issue.

    Best regards,

    Cole Wu


    MSDN Community Support<br/> Please remember to click &quot;Mark as Answer&quot; the responses that resolved your issue, and to click &quot;Unmark as Answer&quot; if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact <a href="mailto:MSDNFSF@microsoft.com">MSDNFSF@microsoft.com</a>.

    Wednesday, April 26, 2017 2:37 AM