What is the best way to instantiate and dispose Db

2020-01-30 04:59发布

问题:

MVC 3 + EF 4.1

I'm choosing between two approaches to deal with DbContext:

  1. Instantiate in Application_BeginRequest, put it into HttpContext.Current.Items and dispose in Application_EndRequest.
  2. Create disposable UnitOfWork (kindof wrapper for DbContext) and start each controller action with using(var unitOfWork = new UnitOfWork()) { ... }

Share your experience please: Which one would you prefer? what are pros and cons for each approach?

回答1:

I would suggest you use a Dependency Injection framework. You can register your DbContext as per request

 container.RegisterType<MyDbContext>().InstancePerHttpRequest();

And inject it as a constructor parameter to the controller.

public class MyController : Controller
{
    public MyController(MyDbContext myDbContext)
    {
         _myDbContext = myDbContext;
    }
}

If the registered type implements IDisposable then the DI framework will dispose it when the request ends.

1st approach: It is much more cleaner to use ID framework than manually implementing it. Further all your requests may not need your UoW.

2nd approach: The controller should not know how to construct your UoW(DbContext). Purpose is not reduce the coupling between components.



回答2:

We currently use repositories injected with UoW (unit of work) instantiated via service locator from an repository factory. Unity controls the lifetime this way taking the work away from you.

Your particular implementation will vary depending if your using POCO's, Entity Objects, etc..

Ultimately you want UoW if your going to be working with more than one objectset in your controller to ensure your just using one context. This will keep your transactions in check etc.

If your going to use multiple objectcontexts (ie. multiple EDMX's), you'll want to look at using UoW with MSDTC...but thats probably more than you wanted to know. In the end, the important thing is to ensure you just instantiate what you need for the controller action (i.e. one instance of the context.). I don't think I'd go with Begin_Request, you may not even need the context for every request.



回答3:

Don't put DbContext in global.asax! :

  1. Static field of DbContext in Global.asax versus instance field of DbContext in controller class?
  2. Entity framework context as static