HiveBrain v1.2.0
Get Started
← Back to all entries
principlecsharpMinor

Returning IQueryable<T> from my repository in Repository pattern design pattern

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
designiqueryablereturningrepositoryfrompattern

Problem

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, 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 : IRepository
  where T : class
{
    protected DbContext _entities;
    protected readonly IDbSet _dbset;

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

    public virtual IQueryable GetAll()
    {

        return _dbset.AsQueryable();
    }

    public IQueryable FindBy(System.Linq.Expressions.Expression> predicate)
    {

        IQueryable 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?

Solution

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.

Context

StackExchange Code Review Q#96070, answer score: 2

Revisions (0)

No revisions yet.