I am using Entity Framework 4.1 and the repository pattern.
I am trying to create methods that will be used throughout most scenarios. I am trying to create a method that brings back records and sorts it according to the order criteria supplied. It can be sorted by 1, 2 or 3 columns. I want this to be specified. I found the following code in the Orchard framework.
In the IRepository interface they have the following (I left out the other methods):
public interface IRepository<T>
{
IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate);
IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order);
}
The implementation for IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order); is:
public class Repository<T> : IRepository<T>
{
public virtual IQueryable<T> Fetch(Expression<Func<T, bool>> predicate)
{
return Table.Where(predicate);
}
public virtual IQueryable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order)
{
var orderable = new Orderable<T>(Fetch(predicate));
order(orderable);
return orderable.Queryable;
}
}
The Orderable class:
public class Orderable<T>
{
private IQueryable<T> _queryable;
public Orderable(IQueryable<T> enumerable)
{
_queryable = enumerable;
}
public IQueryable<T> Queryable
{
get { return _queryable; }
}
public Orderable<T> Asc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = _queryable
.OrderBy(keySelector);
return this;
}
public Orderable<T> Asc<TKey1, TKey2>(Expression<Func<T, TKey1>> keySelector1,
Expression<Func<T, TKey2>> keySelector2)
{
_queryable = _queryable
.OrderBy(keySelector1)
.OrderBy(keySelector2);
return this;
}
public Orderable<T> Asc<TKey1, TKey2, TKey3>(Expression<Func<T, TKey1>> keySelector1,
Expression<Func<T, TKey2>> keySelector2,
Expression<Func<T, TKey3>> keySelector3)
{
_queryable = _queryable
.OrderBy(keySelector1)
.OrderBy(keySelector2)
.OrderBy(keySelector3);
return this;
}
public Orderable<T> Desc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = _queryable
.OrderByDescending(keySelector);
return this;
}
public Orderable<T> Desc<TKey1, TKey2>(Expression<Func<T, TKey1>> keySelector1,
Expression<Func<T, TKey2>> keySelector2)
{
_queryable = _queryable
.OrderByDescending(keySelector1)
.OrderByDescending(keySelector2);
return this;
}
public Orderable<T> Desc<TKey1, TKey2, TKey3>(Expression<Func<T, TKey1>> keySelector1,
Expression<Func<T, TKey2>> keySelector2,
Expression<Func<T, TKey3>> keySelector3)
{
_queryable = _queryable
.OrderByDescending(keySelector1)
.OrderByDescending(keySelector2)
.OrderByDescending(keySelector3);
return this;
}
}
So a way in which this can be used will be as follows:
var foos = _fooRepos.Fetch(
f => f.Name == "two" || f.Name == "three",
o => o.Asc(f => f.Name, f => f.Id)
);
Is this the best possible way of doing what I am trying to achieve? I am trying to make it as simple as possible. I would appreciate all help and if any sample code and articles.
I’m sure the Orchard guys have their reasons (haven’t looked at the code base), but I’m just wondering what it brings to the table compared with a more ‘standard’ LINQ/IQueryable-based solution?
usage:
or