Search code examples
c#design-patternsentity-framework-4.1entity-framework-5repository-pattern

Repository pattern by using entity framework


Following is my code. I want to know it is true or not.

public interface IRepository<T> : IDisposable
{
    IQueryable<T> GetAll();
    T Update(T entity);
    T Insert(T entity);
    T GetById(T entity);
    void Delete(T entity);
    void Save();
}

public class Repository<T> : IRepository<T> where T : class
{
    private readonly SchoolDBEntities _context;

    public Repository(SchoolDBEntities context)
    {
        _context = context;
    }

    public IQueryable<T> GetAll()
    {
        return _context.Set<T>();
    }

    public T Update(T entity)
    {
        var result = _context.Set<T>().Attach(entity);
        _context.Entry(entity).State = EntityState.Modified;
        return result;
    }

    public T Insert(T entity)
    {
        return _context.Set<T>().Add(entity);
    }

    public T GetById(T entity)
    {
        return _context.Set<T>().Find(entity);
    }

    public void Delete(T entity)
    {
        _context.Set<T>().Remove(entity);
    }

    public void Save()
    {
        _context.SaveChanges();
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

The problem is, I don't know when and where to call the Save and Dispose methods.


Solution

  • Don't do dispose in IRepository<T>

    Try UnitOfWork pattern like this

    public interface IUnitOfWork : IDisposable
    {
        IRepository<Cart> CartRepository { get; }
        IRepository<Product> ProductRepository { get; }
        void Save();
    }
    
    public class UnitOfWork : IUnitOfWork
    {
        readonly SqlDbContext _context;
        public UnitOfWork()
        {
            _context = new SqlDbContext();
        }
    
        private bool _disposed;
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _context.Dispose();
                }
            }
            _disposed = true;
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        public void Save()
        {
            _context.SaveChanges();
        }
    
        public IGenericRepository<Cart> CartRepository
        {
            get { return new Repository<Cart>(_context); }
        }
    
        public IGenericRepository<User> UserRepository
        {
            get { return new Repository<User>(_context); }
        }
    }
    

    You can call it like this

    using (_unitOfWork) 
    { 
       var p = _unitOfWork.ProductRepository.SingleOrDefault(p => p.Id == productId); 
       _cartRepository.Add(p);
       _unitOfWork.Save(); 
    }