The entity type <type> is not part of the model for the current context

Viewed 275227

I am getting into the Entity Framework, but I am unsure if I am missing a critical point in the code-first approach.

I am using a generic repository pattern based on the code from https://genericunitofworkandrepositories.codeplex.com/ and have created my entities.

But when I try to access or modify the entity I run into the following:

System.InvalidOperationException: The entity type Estate is not part of the model for the current context.

It happens when I am trying to access it from my repository:

public virtual void Insert(TEntity entity)
{
    ((IObjectState)entity).ObjectState = ObjectState.Added;
    _dbSet.Attach(entity); // <-- The error occurs here
    _context.SyncObjectState(entity);
}

The database (./SQLEXPRESS) is created just fine, but the entities (tables) is just not created on startup.

I am wondering if I need to explicit set the mapping of the entities? Is EF not able to this by its own?

My Entity is:

public class Estate : EntityBase
{
    public int EstateId { get; set; }
    public string Name { get; set; }
} 

My context is as so:

public partial class DimensionWebDbContext : DbContextBase // DbContextBase inherits DbContext
{
    public DimensionWebDbContext() :
        base("DimensionWebContext")
    {
        Database.SetInitializer<DimensionWebDbContext>(new CreateDatabaseIfNotExists<DimensionWebDbContext>());
        Configuration.ProxyCreationEnabled = false;
    }

    public new IDbSet<T> Set<T>() where T : class
    {
        return base.Set<T>();
    }

}

Is there any specific reason why this error occurs? I have tried enable migrations and enable automatic migrations without any help either.

24 Answers

My issue was resolved by updating the metadata part of the connection string. Apparently it was pointing at the wrong .csdl / .ssdl / .msl reference.

For me the issue was that I used the connection string generated by ADO.Net Model (.edmx). Changing the connection string solved my issue.

This can also occur if you are using a persisted model cache which is out of date for one reason or another. If your context has been cached to an EDMX file on a file system (via DbConfiguration.SetModelStore) then OnModelCreating will never be called as the cached version will be used. As a result if an entity is missing from your cached store then you will get the above error even though the connection string is correct, the table exists in the database and the entity is set up correctly in your DbContext.

The message was pretty clear but I didn't get it at first...

I'm working with two Entity Framework DB contexts sysContext and shardContext in the same method.

The entity I had modified\updated is from one context but then I tried to save it to the other context like this:

invite.uid = user.uid;

sysContext.Entry(invite).State = EntityState.Modified;

sysContext.SaveChanges(); // Got the exception here

but the correct version should be this:

invite.uid = user.uid;

shardContext.Entry(invite).State = EntityState.Modified;

shardContext.SaveChanges();

After passing the entity to the correct context this error went away.

I was facing the same issue with EntityFrameworkCore trying to update a range of values.

This approach did not work

  _dbSet.AttachRange(entity);
  _context.Entry(entity).State = EntityState.Modified;
   await _context.SaveChangesAsync().ConfigureAwait(false);

After adding UpdateRange method and removing attach and entry everything work

  _dbSet.UpdateRange(entity);
  await _context.SaveChangesAsync().ConfigureAwait(false);

if you are trying DB first then be sure that your table has primary key

Visual Studio 2019 seems to cause this for me. I fixed it by generating the edmx model again in 2017.

For me it was caused because I renamed the entity class.When I rolled it back it was Ok.

I had this

using (var context = new ATImporterContext(DBConnection))
{
    if (GetID(entity).Equals(0))
    {
        context.Set<T>().Add(entity);
    }
    else
    {
        int val = GetID(entity);
        var entry = GetEntryAsync(context, GetID(entity)).ConfigureAwait(false);
        context.Entry(entry).CurrentValues.SetValues(entity);

    }
    
    await context.SaveChangesAsync().ConfigureAwait(false);
}

This was in an async method, but I've forgot to put await before GetEntryAsync, and so I got this same error...

Make sure you have set up your mapping class to point to your SQL table

I've had the same problem and in my case, the reason why I got this error message was that the property identifiers in my class file did not match the identifiers defined in the database, e.g. I wrote an identifier with a beginning uppercase letter while in the database it was all lowercase.

I've faced this issue after publishing my project using web deploy. It happened because my the metadata in connection string of my publish profile was not same as connection string in my project because I dropped the edmx for some reason and added it back with different Name. To fix it I had to delete the publish profile and redeploy again so that the metadata matches the names.

With models created from database (First Database), it is not possible to replace the connection string (with metadata and providerName="System.Data.EntityClient", from EDMX) by one of SQL.

The only possibility I have found is to create another context that uses the SQL connection (providerName="System.Data.SqlClient")

<connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient"  connectionString="Max Pool Size=10000;Pooling=true;Data Source=MyIpServer;Initial Catalog=myDatabase;Persist Security Info=True;User ID=MyUser;Password=MyPassword;TrustServerCertificate=False" />
    <add name="Entities" providerName="System.Data.EntityClient"  connectionString="metadata=res://*/Datos.MyModel.csdl|res://*/Datos.MyModel.ssdl|res://*/Datos.MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Max Pool Size=10000;Pooling=true;data source=MyIpServer;initial catalog=myDatabase;persist security info=True;user id=MyUser;password=MyPassword;trustservercertificate=False;MultipleActiveResultSets=True;App=EntityFramework&quot;" />
</connectionStrings>

With the two context options, with Identity:

public partial class ContextWithUsers : IdentityDbContext<MyUser>
{
    public ContextWithUsers() : base("name=DefaultConnection")
    {
    }
}

public class MyUser : IdentityUser
{
    // aditional table user data
    //public virtual MyUserInfo MyUserInfo { get; set; }
}

Normal context:

public partial class ContextWithoutUsers : DbContext
{
    public ContextWithoutUsers () : base("name=Entities")
    {
    }
}

This solution works, but... Why is it not possible to use the same context with the First Database model + Identity ?

NOTE 1: if you force change connection string show:

System.Data.Entity.Infrastructure.UnintentionalCodeFirstException: 'The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715'

NOTE 2: External Class library with EDMX + Data and ASP.NET webform project

Delete the .edmx file and add it again. Especially, if you have upgraded the Entity Framework.

Could be stupid, but if you only got this error on some Table, dont forget to clean your project and rebuild (could save a lot of time)

Related