Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC + EF4 + POCO - How to go about storing the Entity Context?

I'm making a start on an MVC project, having gone through the MvcMusicStore tutorial. I'm trying to get my head around how the POCO-generated data/entity context is intended to be stored.

In the samples, the controller generates a copy of the entity context, and all operations complete there:

        MusicStoreEntities storeDB = new MusicStoreEntities();

        //
        // GET: /Store/

        public ActionResult Index()
        {
            // Retrieve list of Genres from database
            var genres = from genre in storeDB.Genres
                         select genre.Name;
            [...]

If I'm to split my solution into layers, what is the standard practice (or key options) for retaining the context? Do I generate it in the controller, and pass it to the repository, or is it possible for the repository to keep a general-use copy?

I understand that the the above would be necessary to use the Unit of Work pattern.

My layers are:

  • Data (edmx file)
  • Entities (Generated from POCO)
  • Repository
  • Mvc web app

My other questions: - What is the overhead of generating the context? - As there is no .Close(), and it doesn't implement IDisposable, is the ObjectContext behind it generating individual connections, connection pooling, sharing a single instance? - Is it possible to lock an ObjectContext if it's passed around between layers / operations too much?

Thanks in advance.

like image 775
Overflew Avatar asked Feb 26 '23 20:02

Overflew


2 Answers

I don't want to go into too much detail/code here, so i'll just mention some points:

  1. Your controller can work with multiple repositories
  2. There should be one repository per aggregate root
  3. Controller work amongst multiple repositories are made possible by Unit of Work
  4. Use a DI container to handle lifetime management of Unit of Work (which is actually the context)
  5. Do not use singletons for the Context, let the DI container instantiate/dispose of the context per HTTP request
like image 108
RPM1984 Avatar answered Mar 11 '23 19:03

RPM1984


I create a single repository for each controller and put my context in there. The rules I follow are that the repository handles anything that I might want to mock (not really the definition of repository, but it works for me). The repository can call other repositories if necessary, but the controller shouldn't have to know about it. The Context is an instance property of the repository and is created on demand (I haven't taken the leap into IOC yet). If the repository calls another repository, it passes the Context instance.

It looks a little like this...

public class MyController : Controller
{
    public IMyControllerRepository Repository { get; set; }
    public ActionResult MyAction(int id)
    {
        var model = Repository.GetMyModel(id);
        return View(model);
    }
}

public class MyControllerRepository : IMyControllerRepository
{
    public MyContext Context { get; set; };
    public MyModel GetMyModel(int id)
    {
        return (from m in Context.MyModels
                where m.ID = id
                select m).SingleOrDefault();
    }
}
like image 41
Brian Avatar answered Mar 11 '23 21:03

Brian