Stored procedures cannot be composed; there's no way to select a certain range of rows returned from the procedure.
There appear to be four options:
- Use
.ToList()
, as Er Daljeet Singh suggested in the comments:
result = source.ToList();
count = result.Count;
if (pageSize > 0)
{
result = result.Skip(pageSize * pageIndex).Take(pageSize).ToList();
}
- Use two separate stored procedures - one to count the total results, and one to retrieve a single page of data.
- Convert your stored procedure to a view or a table valued function[^].
- Use a custom extension method to extract a single page of data and count the total number of records in one hit. That way, you don't have to copy all of the results to a
List<T>
and then throw most of them away.
Something like this should work:
public static class Extensions
{
public static List<T> GetPage<T>(this IEnumerable<T> source, int pageSize, int pageIndex, out int totalCount)
{
if (source == null) throw new ArgumentNullException("source");
if (pageSize < 0) throw new ArgumentOutOfRangeException("pageSize");
if (pageIndex < 0) throw new ArgumentOutOfRangeException("pageIndex");
if (pageSize == 0)
{
var result = source.ToList();
totalCount = result.Count;
return result;
}
int index = 0;
int startIndex = pageSize * pageIndex;
int endIndex = startIndex + pageSize;
var pageOfData = new List<T>(pageSize);
foreach (T item in source)
{
if (startIndex <= index && index < endIndex)
{
pageOfData.Add(item);
}
index++;
}
totalCount = index;
return pageOfData;
}
}
...
public static List<T> GetList<T>(this ISingleResult<T> source, int pageSize, int pageIndex, out int resultCount)
{
List<T> result = null;
int count = 0;
TransactionWrapper(() =>
{
result = source.GetPage(pageSize, pageIndex, out count);
});
resultCount = count;
return result;
}