4
\$\begingroup\$

I am developing an application based on Repository design pattern. What should be the return type from the Repository?

This is my UserRepository class:

public class UserRepository : Repository<UserMaster>, IUserRepository
{
    public UserRepository(DbContext context)
        : base(context)
    {

    }
    public UserMaster GetById(int id)
    {
        return FindBy(x => x.Userid == id).FirstOrDefault();
    }

}

The base Repository class:

public abstract class Repository<T> : IRepository<T>
  where T : class
{
    protected DbContext _entities;
    protected readonly IDbSet<T> _dbset;

    public Repository(DbContext context)
    {
        _entities = context;
        _dbset = context.Set<T>();
    }

    public virtual IQueryable<T> GetAll()
    {

        return _dbset.AsQueryable<T>();
    }

    public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {

        IQueryable<T> query = _dbset.Where(predicate).AsQueryable();
        return query;
    }

    public virtual T Add(T entity)
    {
        return _dbset.Add(entity);
    }

    public virtual T Delete(T entity)
    {
        return _dbset.Remove(entity);
    }

    public virtual void Edit(T entity)
    {
        _entities.Entry(entity).State = System.Data.Entity.EntityState.Modified;
    }

    public virtual void Save()
    {
        _entities.SaveChanges();
    }
}

Is this the right way to return IQueryable from the repository? If I want to join two tables, where should I implement the join logic? Inside or outside the repository?

Currently my return type is IQueryable from the Repository and I am doing join on the Business layer after calling GetAll() function (returns IQueryable) of the required tables. Is this the right approach?

\$\endgroup\$
  • \$\begingroup\$ If i want to join two tables, where should i implement the join logic? has been asked before. \$\endgroup\$ – Mast Jul 7 '15 at 10:29
  • 1
    \$\begingroup\$ If you're getting a user by it's primary key ID, I'd expect you to call .SingleOrDefault() rather than .FirstOrDefault(). \$\endgroup\$ – Jesse C. Slicer Jul 7 '15 at 20:07
2
\$\begingroup\$

IQueryable is a leaky abstraction(you don't wan't to know anything about sql in the service layer). It is also very difficult to test.

I would recommend not returning IQueryable. I would return IEnumerable or ICollection and make my queries run in the repository(ToList on the repository).

I would create queries in my repositories to handle the joins. You can test your queries separately for correctness and performance.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.