entity-frameworkninject

Clear Entity Framework context on exception


I am working on an ASP.NET MVC website, and am using Entity Framework to save/update data into my database.

I am using ninject to inject dbContext into my repository class like below:

public class MyRepository : IMyRepository
{
    MyContext _context;

    public MyRepository(MyContext context)
    {
        _context = context;
    }

    // more code ...

This is how I am injecting the context using ninject:

kernel.Bind<MyContext>().ToSelf().InSingletonScope();

And I am using the injected dbContext as below to save the data into my database:

public void InsertModel(MyModel r)
{
    _context.MyModel.Add(r);
    _context.SaveChanges();
}

Now, the problem I am facing is that if an exception occurs (for example if I purposely pass an invalid Model), Entity Framework will throw an exception. The invalid entity remains in the dbContext and all further save attempts will fail because of that.

I have been googling this issue and found This Article which suggests putting save / update operation in a try / catch block. If any exception occurs, it suggests to clear dbContext in the catch block.

Is this the correct appraoch? It sounds like a lot of work to put a try / catch around every save operation and clear the dbContext? I Would appreciate any help on explaining the correct approach for clearing the context.


Solution

  • You need to create one dbContext per Web Request. Don't share your dbContext among different requests: dbContext lifecycle management

    dbContext is Lightweight and is not expensive to create, so don't worry about performance: MSDN

    If you are using ninject, you can use InRequestScope instead of InSingletonScope. InRequestScope will ensure the lifetime of your Entity Framework dbContext does not exceed the lifetime of your Http WebRequest and dispose your dbContext at the end of each request.

    kernel.Bind<MyContext>().ToSelf().InRequestScope();
    

    Side Note: If you are using Repository pattern, make sure you use InRequestScope for your repository as well. Repository is dependant on dbContext, and you will run into problem, if your dbContext is disposed while the Repository is still in use.

    kernel.Bind<IMyRepository>().To<MyRepository>().InRequestScope();