user1874700
user1874700

Reputation: 23

How to manage DbContext in EF 6

At very first, every time when I use GYOSContext, I just create a new instance to do the CRUD operations. Since some of my data model is not simple, I always met an exception of

EF:An entity object cannot be referenced by multiple instances of IEntityChangeTracker

I guess the problem is caused because there are multiple DbContext instances working on the same data model. So I try to store DbContext in the session, each time for manager class will get the same instane of DbContext, which solve my problem perfectly.

The question is that I'm not quite sure if it is good solution or not. Please give me some suggestions.

Thank you very much.

Code at first :

public class GYOSContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Item> Items { get; set; }
    public DbSet<Coupon> Coupons { get; set; }
    public DbSet<Order> Orders { get; set; }
}

Code improved :

 public class GYOSContext : DbContext
{
    private GYOSContext()
    {

    }

    public static GYOSContext GetGyosContext()
    {
        var db = HttpContext.Current.Session["GYOSContext"] as GYOSContext;
        if (db == null)
        {
            db = new GYOSContext();
            HttpContext.Current.Session["GYOSContext"] = db;
        }
        return db;
    }
    public DbSet<User> Users { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Item> Items { get; set; }
    public DbSet<Coupon> Coupons { get; set; }
    public DbSet<Order> Orders { get; set; }
}

Upvotes: 0

Views: 552

Answers (2)

gzarzar
gzarzar

Reputation: 115

it is not a good practice to manage DbContext by storing at session level, application level or by using single tone pattern, i will go with creating the context at controller level like the sample below:

public class HomeController : Controller
{
    private DbContext db;

    public HomeController(DbContext db)
    {
        this.db = db;
    }

    public ActionResult Index()
    {
        // Do stuff with context
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
            db.Dispose();
        base.Dispose(disposing);
    }

} 

Upvotes: 1

Eric J.
Eric J.

Reputation: 150108

It is never wise to store your context in session.

Each controller action should create an instance of GYOSContext, and dispose of that instance once the action completes.

The pattern should be something like

public ActionResult DoSomething()
{
    using (GYOSContext context = new GYOSContext())
    {
        // Do stuff with context

    }  // Automatically disposed when exiting scope of using block
}

Upvotes: 2

Related Questions