How to identify Dbcontexts (to prevent singleton context for entire application)

asp.net-mvc c# entity-framework

Question

In order to avoid using a single Dbcontext for your whole application, I was wondering how to scope out your Dbcontexts in Entity Framework. Since I'm new to Entity Framework and have only read tutorials using a single Dbcontext as an example, EF is now mostly a mystery to me.

Consider, for instance I have three types:

  • Post
  • User
  • Comment

Each model has a connection to the others (A Post belongs to User, Comment belongs to User and Post). Do I create a Dbcontext for every single one separately? However, because they are all connected, it wouldn't be acceptable. Should I instead create a Dbcontext for each case I require? For instance, a PostCommentsContext would be used if I just needed to query for Posts and Comments, not users. A PostUserCommentContext would then exist.

1
11
2/7/2017 12:07:00 AM

Accepted Answer

Use of a Work Unit to encapsulate the Data Context, manage the connection lifespan, and let you to interact with numerous Repositories would be the best course of action (if you were so inclined to go down that path).

Implementation summary:

  • Make a user interface (IUnitOfWork ) that reveals characteristics for yourDbSet 's, together with a single technique known as Commit
  • Put a plan into action (EntityFrameworkUnitOfWork ), carrying out as necessary. Calling SaveChanges on the base class is all that commit does (DbContext ), and moreover offers a strong hook-in for impromptu logic.
  • Your controller will approve aIUnitOfWork utilize DI to solve a problem, ideallyEntityFrameworkUnitOfWork , with a setting of lifetime with HTTP-context scoping (StructureMap is good for this)
  • (Optional but advised) make a Repository that also incorporates theIUnitOfWork Now use your Controller to burn off that energy.

HTH

EDIT - Reaction to Remarks

Oh, how can you do work that involves creating records in multiple models then? i.e., create a new user and a new post in the same transaction.

Considering that you're using ASP.NET MVC, your controllers need to take anIUnitOfWork in their builder.

Based on what you requested, here is an illustration.

public SomeController : Controller
{
   private IUnitOfWork _unitOfWork;
   private IUserRepo _userRepo;
   private IPostRepo _postRepo;

   public SomeController(IUnitOfWork unitOfWork, IUserRepo userRepo, IPostRepo postRepo)
   {
      _unitOfWork = unitOfWork; // use DI to resolve EntityFrameworkUnitOfWork
      _userRepo = userRepo;
      _postRepo = postRepo;
   }

   [HttpPost]
   public ActionResult CreateUserAndPost(User user, Post post)
   {
      // at this stage, a HTTP request has come in, been resolved to be this Controller
      // your DI container would then see this Controller needs a IUnitOfWork, as well
      // as two Repositories. DI smarts will resolve each dependency.
      // The end result is a single DataContext (wrapped by UoW) shared by all Repos.
      try
      {
         userRepo.Add(user);
         postRepo.Add(post);
         // nothing has been sent to DB yet, only two objects in EF graph set to EntityState.Added
         _unitOfWork.Commit(); // two INSERT's pushed to DB
      }
      catch (Exception exc)
      {
          ModelState.AddError("UhOh", exc.ToString());
      }
   }
}

And one more question, what does the HTTP-context scoped lifetime do?

Scope management options for objects in DI-talk include per thread, per session, per http request, singleton, etc.

Web programs should use the HTTP-context scoped option. It translates to "create a context when an HTTP request arrives and destroy it after the request is complete."

7
1/28/2011 4:36:00 AM

Popular Answer

Use only one DbContext! Your life will be easier as a result. You shouldn't be concerned about performance since data that isn't required or accessed won't be loaded or use any resources.

public class UserContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<Comment> Comments { get; set; }
}

You could need two or more contexts for some instances.

One context, similar to the one described above, to keep all the front-end data required for your application to function, and another context, for instance, to store reports produced from that front-end data and which is only utilized in the back-end of your application.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow