My advise would be to create an extension method of any IQueryable<T>
, that fetches page pageNr
of size pageSize
. Something like this:
public static ICollection<T> FetchPage<T>(this IQueryable<T> source,
int pageNr, int pageSize)
{
// TODO: implement
}
and the async version:
public static async Task<ICollection<T>> FetchPageAsync(this IQueryable<T> source,
int pageNr, int pageSize) {...}
Usage would be:
var query = from a in ctx.Appeals ...
select new Appeal
{
...
});
// Using page size 25, fetch page 5:
ICollection<Appeal> page5 = query.FetchPage(5, 25);
// Using page size 25, fetch page 20 async:
ICollection<Appeal> page5 = await query.FetchPageAsync(20, 25);
// Fetch all Appeals:
ICollection<Appeal> allAppeals = query.FetchPage(5, 0);
If this is what you want, on with the implementation!
If you are not familiar with extension methods, read Extension methods demystified
The code for the sync and the async version are almost the same, so I'd create a common extension method first:
public static IQueryable<T>> QueryPage(this IQueryable<T> source,
int pageNr, int pageSize)
{
// TODO: check input: source not null, pageNr / pageSize not negative, etc
// zero pageSize: return all:
if (pageSize == null)
return source;
else
return source.Skip(pageNr * pageSize).Take(pageSize);
}
Now that you've got this, the FechPage is a one-liner:
public static ICollection<T> FetchPage<T>(this IQueryable<T> source,
int pageNr, int pageSize)
{
return source.QueryPage(pageNr, pageSize).ToList();
}
public static async Task<ICollection<T>> FetchPageAsync<T>(this IQueryable<T> source,
int pageNr, int pageSize)
{
return await source.QueryPage(pageNr, pageSize).ToListAsync();
}
If you want a proper exception if source equals null, consider to call:
return QueryPage(source, pageNr, pageSize);
the this
parameter in extension methods can also be used as a traditional parameter.