1

I have been learning about MVC and I am using Entity Framework. What I am trying to understand is repositories. Every tutorial I've read deals with one entity and at that level I have a understanding, but what about multiple tables. I use a variation of code-first, where I associate my model classes with an existing database. In my database,there are three tables; User, Journey and UserJourney (linked table). User and Journey have a many-to-many relationship. Should I have a repository for each entity? Has aggregates any use here? In the long run I want to query the database to find user's journeys and pass to a view.

My question is perhaps vague, but I am quite confused on this matter, so any help in understanding this would be appreciated!

Colin Roe
  • 774
  • 1
  • 18
  • 35

2 Answers2

3

Normally repositories should not be defined for each entity but rather per aggregate root. You have entities that cannot live by themselves, but are related to some parent entity. This parent entity is called aggregate root and you should have a repository for each of them.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    Ok, I have User and Journey tables that have a many to many relationship. So I now also have a linked UserJourney table. Would these three tables make up an aggregate? What would be the aggregate root? I assume User. – Colin Roe Jul 12 '13 at 14:02
2

Search for a concept called GenericRepository. It will help in getting rid of the repository for each entity problem. Sample below:

public interface IGenericRepository<T> where T : class
{
    IEnumerable<T> GetAll();
    T SingleOrDefault(Expression<Func<T, bool>> predicate);
    IEnumerable<T> Get(Expression<Func<T, bool>> predicate);
    void Insert(T entity);
    void Update(T entity);
    void Delete(object id);
    void Delete(T entity);
}

public class GenericRepository<T> : IGenericRepository<T> where T : class
{
    readonly MyDbContext _context;
    readonly DbSet<T> _dbSet;
    public GenericRepository(PfsDbContext context)
    {
        _context = context;
        _dbSet = context.Set<T>();
    }

    public virtual IEnumerable<T> GetAll()
    {
        return _dbSet.AsEnumerable();
    }

    public T SingleOrDefault(Expression<Func<T, bool>> predicate)
    {
        return _dbSet.Where(predicate).SingleOrDefault();
    }

    public IEnumerable<T> Get(Expression<Func<T, bool>> predicate)
    {
        return _dbSet.Where(predicate);
    }

    public void Insert(T entity)
    {
        _dbSet.Add(entity);
    }

    public void Update(T entityToUpdate)
    {
        _dbSet.Attach(entityToUpdate);
        _context.Entry(entityToUpdate).State = EntityState.Modified;
    }

    public void Delete(T entity)
    {
        if (_context.Entry(entity).State == EntityState.Detached)
        {
            _dbSet.Attach(entity);
        }
        _dbSet.Remove(entity);
    }

    public void Delete(object id)
    {
        var entityToDelete = _dbSet.Find(id);
        Delete(entityToDelete);
    }
  }

You can then use it as

var userRepository = new GenericRepository<User>(_context);
var journeyRepository = new GenericRepository<Journey>(_context);
sunil
  • 5,078
  • 6
  • 28
  • 33