Question

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.

Was it helpful?

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(); 
}

OTHER TIPS

I think it depends on the way you use this repo. So save when you want to save and dispose when you want to finish your work ... on application close etc..

As you use a Unit of Work pattern here, obviously you should call Save method if user (of a repository) send save changes command. It could be a person clicking Apply changes button on one of your Edit forms or other part of your application which handles some transaction logic and saves/discards changes based on it. So basically, when the logical set of changes is ready to be save, Repository takes care of it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top