Search code examples
asp.net-mvcperformanceentity-frameworkmef

Is NonShared DbContext in MVC a bad practice?


It is an MVC application with Entity Framework Code First for the ORM and MEF as the IoC. If I mark the DbContext with PartCreationPolicy.Shared there is an error saying the object already exists in the container every time I try to perform an edit. But what if I simply mark the DbContext with PartCreationPolicy.NonShared so it gets created for every request? Is there a terrible performance impact for that?

Update Here is the code for save:

Provider IRepository<Provider>.Put(Provider item)
        {
            if (item.Id == Guid.Empty)
            {
                item.Id = Guid.NewGuid();
                this.Providers.Add(item);
            }
            else this.Entry<Provider>(item).State = EntityState.Modified;
            return item;
        }

And this is the error when on Shared

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.


Solution

  • You should definitely use PartCreationPolicy.NonShared. Everything you can read about context lifecycle management, whether it's linq to sql, entity framework, or NHibernate (sessions), will agree upon one thing: the context should be short-lived. An easy rule of the thumb is: use it for one unit of work, which means: create a context, do stuff, call SaveChanges once, dispose. Most of the times this rule works well for me.

    A shared (or singleton) context is the pattern that hits performance, because the context gets bloated over time. The change tracker needs to track more and more objects, relationship fixup will get slower. And you will find yourself refreshing (re-loading) entities time and again.