Invalidoperationexception when using the Databasecontext Set method

Asked

Viewed 122 times

0

When using the Dbcontext.Set() method, the following exception is raised:

The Entity type is not part of the model for the Current context

If I create a Dbset directly in Databasecontext, it works. But my current need is to create a generic repository, and from it get the Dbset referring to entity passed in parameter, as shown in the code below.

What’s wrong with the implementation to lift this Exception? I’m using Codefirst.

Controller

public class QualquerController<TEntidade> : Controller
{
    public DatabaseContext contexto;

    public Repositorio<TEntidade> repositorio;

    public QualquerController()
    {
            repositorio = new Repositorio<TEntidade>(contexto);
    }
}

Repository

public class Repositorio<TEntidade> : where TEntidade : EntidadeBase
{
    public DbSet<TEntidade> Entidade;

    public Repositorio(DatabaseContext contexto)
    {
         Entidade = contexto.Set<TEntidade>();
    }
}
  • forehead without that line Entidade = contexto.Set<TEntidade>();. I don’t think you need this

  • Hi Lucas, I’m not in my Dbcontext, so I need this line to instantiate the Dbset. If I shoot, gives Nullreferenceexception.

  • This entity you are trying to add already exists in this context?

2 answers

1

The point is that the method contexto.Set<TEntidade>() does not add this entity to the context. It only returns a Dbset so you can manipulate the repository.

  • I imagined that this was the reason, but my implementation follows several examples on the internet that supposedly work... Do you know any way to improve this code to avoid this Exception? As I told you, if I create a Dbset<T> directly in Databasecontext, it works correctly, but I need to do it in a generic way with n dbsets.

  • How will you manage the tables in the database if you do not put them in Dbcontext? The way you want to do it, a table will only exist when the entity controller is called. So say Voce has 2 tables. The first is called when you start the application (at this point it is created). And the second is called when you click on a link. You will create the tables separately at runtime if they do not exist?

  • Lucas, how do you suggest then? I need a generic Repository. I have worked on projects where there was only one Dbcontext without dbSet, however, the mapping of the classes were in Onmodelcreating. I don’t have this mapping because I’m using data Annotations. There is another way to add tables to context without using dbSet so I can keep dbset creation in the repository, not context?

  • Vinicius, there is always a way. But as I said in the comment above, the tables need to be managed in the same Dbcontext class. Or by Dbset or Onmodelcreating.

  • 1

    I will try to better explain the need for centralized management. You create the Customers table only when you access the customer page. Then you go to another screen. When you go back to the customer screen, will you check again if the table exists? This will consume many machine resources. And to have a centralized management, the only way is with Dbcontext. All the Orms I know manage the tables centrally. All in one place. And always checked at application startup. I hope I’ve helped :)

  • Yes helped Lucas, through his comment I managed to perform the initialization of the tables in Onmodelcreating, as said in my reply below. If you have any scores on the method I implemented to record the tables in context, please do so :)

Show 1 more comment

1


I was able to solve the problem through the tips that Lucas informed me. Using the Entity method of the modelbuilder passed as parameter in the Onmodelcreating method, I was able to register my entities in the context. Below is the code used:

public class DatabaseContext : DbContext
{
     public DatabaseContext()
        : base("DefaultConnection")
    {
        Database.SetInitializer<DatabaseContext>(new DropCreateDatabaseAlways<DatabaseContext>());
    }

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
         modelBuilder.Entity<Foo>();
         modelBuilder.Entity<Bar>();

         base.OnModelCreating(modelBuilder);
     }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.