ratul keot
asked on
Paginate database records using stored procedure
Hi, I have a blog website build using ASP.NET using C# and entity framework.
I have this requirement where I need to list all my published blogs and paginate them as they are too many.
I am new to .NET and have no idea how to do it.
Earlier I got all the blog details from the database and used ajax and JSON as well to fetch it.
A friend gave me a sample code and told me it would help. Please have a look into that as well.
Please help me acheive this.
I am attaching all my code here along with the stored procedure.
STORED PROCEDURE
DAL Sample Code
I hope I am able to explain the situation clearly. I can provide more data If required.
I have this requirement where I need to list all my published blogs and paginate them as they are too many.
I am new to .NET and have no idea how to do it.
Earlier I got all the blog details from the database and used ajax and JSON as well to fetch it.
A friend gave me a sample code and told me it would help. Please have a look into that as well.
Please help me acheive this.
I am attaching all my code here along with the stored procedure.
STORED PROCEDURE
GO
/****** Object: StoredProcedure [dbo].[GetBlogs] Script Date: 05-11-2018 01:50:14 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER proc [dbo].[GetBlogs]
@count int,
@start int,
@categoryId int,
@blogCount int Output
as
begin
Declare @LastBlog int
Set @count = 9
Set @lastBlog = @count + @start;
create table #x (id int identity(1,1),blogid int)
if @categoryId is null
begin
insert into #x
select Id from Blog where IsDeleted=0 and StatusId = 2
end
else
begin
insert into #x
select b.Id from Blog b inner join BlogCategories bc on b.Id = bc.BlogId where bc.CategoryId = @categoryId and b.IsDeleted=0 and b.StatusId = 2;
end
select @blogCount = COUNT(#x.id) from #x
select b.* from #x inner join Blog b on #x.blogid = b.Id where #x.id > @start and #x.id <= @LastBlog
drop table #x
end
DAL Sample Code
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
namespace Project.Utility
{
public class DAL
{
#region Variables
public static bool? IsStoredProc = null;
public static int CommandTimeoutSeconds = 240;
public static string ConnectionString = ConfigurationManager.ConnectionStrings["BlogDataModel"].ConnectionString;
#endregion Variables
#region Port Methods
protected static DbConnection CmnDbConnection(string connStr)
{
return new SqlConnection(connStr);
}
protected static DbCommand CmnDbCommand(string query, DbConnection connection)
{
return new SqlCommand(query, connection as SqlConnection);
}
public static DbDataAdapter CmnDbDataAdapter(DbCommand command)
{
return new SqlDataAdapter(command as SqlCommand);
}
public static DbParameter CmnDbParameter(string name, object value)
{
return new SqlParameter(name, value);
}
#endregion Port Methods
#region Methods
public static DataTable Read(string query, DbParameter[] paramList, bool? isStoredProc, int? timeout)
{
DataTable dt = new DataTable();
using (DbConnection connection = CmnDbConnection(ConnectionString))
{
try
{
DbCommand command = CmnDbCommand(query, connection);
if (isStoredProc != null)
{
command.CommandType = isStoredProc.Value ? CommandType.StoredProcedure : CommandType.Text;
}
if (isStoredProc != null && isStoredProc == true)
{
if(paramList!=null)
{
command.Parameters.AddRange(paramList);
}
}
command.CommandTimeout = timeout ?? CommandTimeoutSeconds;
DbDataAdapter adapter = CmnDbDataAdapter(command);
adapter.SelectCommand.Connection.Open();
adapter.Fill(dt);
}
catch (Exception exception)
{
throw exception;
}
}
return dt;
}
public static int Insert(string query, int? timeout)
{
int returnValue = 0;
using (DbConnection connection = CmnDbConnection(ConnectionString))
{
try
{
DbCommand command = CmnDbCommand(query, connection);
command.CommandTimeout = timeout ?? CommandTimeoutSeconds;
DbDataAdapter adapter = CmnDbDataAdapter(command);
adapter.InsertCommand = command;
adapter.InsertCommand.Connection.Open();
adapter.InsertCommand.ExecuteNonQuery();
}
catch (Exception exception)
{
throw exception;
}
}
return returnValue;
}
#endregion
}
}
I hope I am able to explain the situation clearly. I can provide more data If required.
ASKER
@Russ Suter- Thanks for the suggestion. I would be grateful if you could show me how to get the data from the stored procedure to the the asp page. I have no clue how to get it. Thank you
I would not use the record ID to paginate because the ID may not always be sequential. A failed insert or deleted record would produce a gap in the ID sequence. Instead use ...psuedo code: SELECT TOP 9 * FROM @tablename WHERE ID NOT IN(SELECT TOP (9 * (@pagenumber -1)) ID FROM @tablename) ORDER BY ID desc
If you are merely looking at statistical data,
Count of records/number of records per page.
I.e. Two queries, one determines row count, one displays .......the requested page.
The following might be another..
http://www.sqlservergeeks.com/sql-server-alternatives-to-top-clause-rowcount-row_number/
Count of records/number of records per page.
I.e. Two queries, one determines row count, one displays .......the requested page.
The following might be another..
http://www.sqlservergeeks.com/sql-server-alternatives-to-top-clause-rowcount-row_number/
Assuming you have a working stored procedure that accepts the @PageNumber argument (@PageSize can easily be a passed variable or a value that is set inside the stored procedure itself), you'd need a SQL Data Connection and a SQL Data Adapter. Your C# code would look something like this:
What you end up with is a data table that contains the requested data. You can then drop that data table into any control that supports DataBinding or manipulate it however you wish.
using (SqlConnection connection = new SqlConnection("[insert your connection string here]"))
{
using (SqlDataAdapter da = new SqlDataAdapter("GetBlogs", connection))
{
DataTable dt = new DataTable();
da.SelectCommand.Parameters.AddWithValue("@Count", 1);
da.SelectCommand.Parameters.AddWithValue("@start", 1);
da.SelectCommand.Parameters.AddWithValue("@categoryId", 1);
da.SelectCommand.Parameters.AddWithValue("@blogCount", 100);
da.Fill(dt);
return dt;
}
}
I'm assuming in your stored procedure example you're using @start as the page number and @blogCount as the page size. Of course you'd need to pass useful variable values rather than constants as I have in this example.What you end up with is a data table that contains the requested data. You can then drop that data table into any control that supports DataBinding or manipulate it however you wish.
Have you considered using Entity framework and PagedList?
https://www.nuget.org/packages/PagedList/
Even easier if you use MVC
https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
https://www.nuget.org/packages/PagedList.Mvc/
https://www.nuget.org/packages/PagedList/
Even easier if you use MVC
https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
https://www.nuget.org/packages/PagedList.Mvc/
Here is a ROW_NUMBER() example for efficiently paging through large amounts of data.
This example is as simple as it gets and plays very well with large tables. Let me know if you need any help getting this sample working with your tables.
It's highly simplified vs. the article, but I made this example for you using the information found at this link.
https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/bb445504(v=msdn.10)
T-SQL stored procedure.
C# pagetest.aspx.
Sample table
This example is as simple as it gets and plays very well with large tables. Let me know if you need any help getting this sample working with your tables.
It's highly simplified vs. the article, but I made this example for you using the information found at this link.
https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/bb445504(v=msdn.10)
T-SQL stored procedure.
USE [yourdb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[pagedisplay] (
@Page int,
@RecsPerPage int
)
AS
SET ROWCOUNT @RecsPerPage
DECLARE @TCount bigint
select @TCount = COUNT(*)from dbo.testtable
BEGIN
WITH USERPAGE AS
(
SELECT ROW_NUMBER() OVER (Order By registered DESC) AS RowNum
,[userid]
,[registered]
,@TCount as 'TotalCount'
FROM dbo.testtable with (Nolock)
)
SELECT *
FROM USERPAGE
WHERE RowNum BETWEEN (@Page - 1) * @RecsPerPage + 1 AND @Page * @RecsPerPage Order By registered DESC
END
C# pagetest.aspx.
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%
//edit me
SqlConnection Conn = new SqlConnection("Server=127.0.0.1;Database=yourdb;UID=user;PWD=pass;");
int PageSize = 100;
//end edit me
String Number = "";
int PNumber = 0;
int CurPage = 1;
if ((Request["Page"] != null) && (Request["Page"] != "")) {
try{CurPage = Convert.ToInt32(Request["Page"]);}
catch { CurPage = 1; }
}
Conn.Open();
SqlCommand Ulook = new SqlCommand("pagedisplay @Page='" + CurPage + "', @RecsPerPage='" + PageSize + "'", Conn);
SqlDataReader UlookSet = Ulook.ExecuteReader();
while (UlookSet.Read()) {Number = UlookSet["TotalCount"].ToString(); } //write your data in that while loop etc.. UlookSet["userid"].ToString() and UlookSet["registered"].ToString() in this example.
UlookSet.Close();
Ulook.Dispose();
Conn.Close();
Conn.Dispose();
try{ PNumber = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(Number) / Convert.ToDecimal(PageSize))); }
catch { PNumber = 1; }
if (PNumber <= 0) { PNumber = 1; }
int TotalPages = PNumber;
int i = CurPage + 1;
int j = CurPage - 1;
int TPO = CurPage - 6;
Response.Write(" Page " + CurPage + " of " + TotalPages + "<br/>");
if (CurPage != 1){ Response.Write(" <a href=pagetest.aspx?page=" + j + ">Previous</a> | "); }
for (int k = 1; k <= 12; k++){
if ((TPO > 1) && (TPO < TotalPages)) {
if (TPO != CurPage){Response.Write(" <a href=pagetest.aspx?page=" + TPO + ">" + TPO + "</a> "); }
else {Response.Write(" [" + TPO + "] ");}
TPO++;
}
}
if ((TotalPages > 1) && (i <= TotalPages)) { Response.Write("| <a href=pagetest.aspx?page=" + i + ">Next</a>"); }
%>
Sample table
USE [yourdb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[testtable](
[userid] [nvarchar](50) NOT NULL,
[registered] [datetime] NULL,
CONSTRAINT [PK_testtable] PRIMARY KEY CLUSTERED
(
[userid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
This question needs an answer!
Become an EE member today
7 DAY FREE TRIALMembers can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Open in new window