c# entity framework: correct use of DBContext class inside your repository class

前端 未结 10 1625
伪装坚强ぢ
伪装坚强ぢ 2020-12-02 10:59

I used to implement my repository classes as you can see below

public Class MyRepository
{
      private MyDbContext _context; 

      public MyRepository(My         


        
10条回答
  •  不知归路
    2020-12-02 11:31

    The first article you linked forgot to precise one important thing: what is the lifetime of the so-called NonScalableUserRepostory instances (it also forgot to make NonScalableUserRepostory implements IDisposable too, in order to properly dispose the DbContext instance).

    Imagine the following case:

    public string SomeMethod()
    {
        using (var myRepository = new NonScalableUserRepostory(someConfigInstance))
        {
            return myRepository.GetMyString();
        }
    }
    

    Well... there would still be some private DbContext field inside the NonScalableUserRepostory class, but the context will only be used once. So it's exactly the same as what the article describes as the best practice.

    So the question is not "should I use a private member vs a using statement ?", it's more "what should be the lifetime of my context ?".

    The answer would then be: try to shorten it as much as possible. There's the notion of Unit Of Work, which represents a business operation. Basically you should have a new DbContext for each unit of work.

    How a unit of work is defined and how it's implemented will depend on the nature of your application ; for instance, for an ASP.Net MVC application, the lifetime of the DbContext is generally the lifetime of the HttpRequest, i.e. one new context is created each time the user generates a new web request.


    EDIT :

    To answer your comment:

    One solution would be to inject via constructor a factory method. Here's some basic example:

    public class MyService : IService
    {
        private readonly IRepositoryFactory repositoryFactory;
    
        public MyService(IRepositoryFactory repositoryFactory)
        {
            this.repositoryFactory = repositoryFactory;
        }
    
        public void BusinessMethod()
        {
            using (var repo = this.repositoryFactory.Create())
            {
                // ...
            }
        }
    }
    
    public interface IRepositoryFactory
    {
        IRepository Create();
    }
    
    public interface IRepository : IDisposable
    {
        //methods
    }
    

提交回复
热议问题