I have the following abstract class which all of my Repositories inherit from:
abstract class RepositoryBase<T> {
void Add();
void Delete();
void SaveChanges();
}
I wanted to add another method for automatically paging an IQueryable<T>
and returning a List<T>
from the results:
protected List<T> Paginate(IQueryable<T> content, int? skip, int? take)
{
if (skip.HasValue) content = content.Skip(skip.Value);
if (skip.HasValue && take.HasValue) content = content.Take(take.Value);
return content.ToList();
}
But, Skip
requires that the source by IOrderedQueryable<T>
. I tried changing the method signature to:
Paginate(IOrderedQueryable<T> content, int? skip, int? take)
But Skip
returns an IQueryable<T>
so I receive the error Cannot convert source type 'System.Linq.IQueryable<T>' to target type 'System.Linq.IOrderedQueryable<T>'
How do I force the implementing class to send my method an IOrderedQueryable<T>
and get my paginate method to work?
It sounds like you should might want to make Paginate
still take an IOrderedQueryable<T>
to validate at compile-time that you've started with something that's ordered - but you don't then need to assign back to the same variable. For example:
protected List<T> Paginate(IOrderedQueryable<T> content, int? skip, int? take)
{
// Different variable type so that we can assign to it below...
IQueryable<T> result = content;
if (skip.HasValue) result = result.Skip(skip.Value);
if (skip.HasValue && take.HasValue) result = result.Take(take.Value);
return result.ToList();
}
And as Marc notes, it would probably be better to change the Take
line to:
if (take.HasValue) result = result.Take(take.Value);
See more on this question at Stackoverflow