Reputation: 1181
I have this generic method:
public IQueryable<TEntity> PaginateAndOrderByDesc<TEntity>(int pageIndex, int pageSize, Expression<Func<TEntity, object>> orderByDescending)
where TEntity : class, IContextEntity
{
int numberOfRecordsToSkip = (pageIndex - 1) * pageSize;
return context.Set<TEntity>().OrderByDescending(orderByDescending).Skip(numberOfRecordsToSkip).Take(pageSize);
}
When I use it:
List<Person> people = repository.PaginateAndOrderByDesc<Person>(1,
30, x = > x.RegistrDate)
.ToList();
I get an error: "Unable to cast the type 'System.DateTime' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types."
How do I make that Generic function work with orderByDescending expression?
Upvotes: 3
Views: 5973
Reputation: 203820
Add a generic argument to represent the type you are ordering on:
public IQueryable<TEntity> PaginateAndOrderByDesc<TEntity, TKey>(
int pageIndex,
int pageSize,
Expression<Func<TEntity, TKey>> sortSelector)
where TEntity : class, IContextEntity
{
int numberOfRecordsToSkip = (pageIndex - 1) * pageSize;
return context.Set<TEntity>()
.OrderByDescending(sortSelector)
.Skip(numberOfRecordsToSkip)
.Take(pageSize);
}
Having said that, I would suggest not including the OrderBy
method within this query. It reduces the readability of your query to combine the "order the data" and "get a certain page" operations. Keep them separate. The "order the data" operation is just fine as it is; you really only need to create a "get a certain page" query:
public static IQueryable<TEntity> GetPage<TEntity>(
this IOrderedQueryable<TEntity> query,
int pageIndex,
int pageSize)
{
int numberOfRecordsToSkip = (pageIndex - 1) * pageSize;
return query.Skip(numberOfRecordsToSkip)
.Take(pageSize);
}
In addition to giving you greater power to compose your queries as you see fit, this more importantly results in more readable queries in which what is happening is very clear based on the methods called.
Upvotes: 5