0

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.

3 Answers 3

2

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(); 
}
Sign up to request clarification or add additional context in comments.

2 Comments

Often, you will run into scenarios where you need to call methods from 2 or more repositories. So, you will have do using (_cartRepository){} and using (_productRepository){}, here essentially you opening and closing a connection to database twice, which can be avoided using the UnitOfWork pattern like this using (_unitOfWork) { var p = _unitOfWork.ProductRepository.SingleOrDefault(p => p.Id == productId); _cartRepository.Add(p); _unitOfWork.Save(); }
Your comment should be part of the answer to add reasoning behind your answer.
0

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..

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.