السلام عليكم ورجمة الله وبركاته
من منا لا يعرف خاصية PageSize أو AllowPaging الموجودة في الـ GridView، وكلنا نعرف أنها تقوم بتقسيم البيانات المستردة من قاعدة البيانات حيث يتم عرضها بطريقة سلسة تعطي مظهر جيد للصفحة الإلكترونية وخصوصا لو كانت هناك أزرار للتنقل مثل التالي والسابق والأخير والأول أو أرقام الصفحات المتوفرة. ولكن دعونا نفكر قليلا ونسأل هل الغرض من هذا التكتيك هو فقط المظهر أم زيادة الفعالية والآداء ؟ هل حقا عندما تقوم بتحديد حجم الصفحة PageSize سيتم إسترجاع فقط العدد المذكور من قاعدة البيانات أم أنه سيتم إسترجاع كافة البيانات ثم ستقوم الـ GridView بعملية التقسيم ؟
سأقوم بشرح طريقة بسيطة جدا تقوم بإسترجاع الصفوف المطلوبة من قاعدة البيانات مباشرة ولكن للأسف الشديد هذه الطريقة لا تصلح إلا لو كان خادم قاعدة البيانات هو MS SQL Server، والسر يكمن لوجود داله إسمها ROW_NUMBER تقوم بإسترجاع رقم الصف بناء على حقل يتم تحديده. لكي تتضح الفكرة سأقوم ببناء الجدول التالي والذي سأسميه people :
بعد ذلك سأقوم بإنشاء الــ Stored Procedure التالي :
create proc get_paged_data @page_index int, @number_of_rows int, @row_count int output as begin select @row_count = (select count(id) from people) declare @starting_index int; set @starting_index = (@page_index * @number_of_rows) + 1; with entries as ( select ROW_NUMBER() over (order by id asc) as row, id, [name], entry_date from people ) select id, [name], entry_date from entries where row between @starting_index and @starting_index + @number_of_rows - 1 end
حيث أنه يستقبل 3 Parameters الأول يمثل رقم الصفحة والثاني يمثل عدد السجلات في الصفحة والثالث يتم تخزين عدد السجلات الكلي والذي سوف أستخدمه لعرض عدد السجلات حتى أتمكن من إظهار معلومات أكثر مثل "يتم عرض عدد كذا من مجموع كذا". كذلك سأنشيء صفحة الغرض منها إدخال عدد سجلات عشوائية حسب ما يتم إدخاله في TextBox ستكون الصفحة بإسم insert.aspx وهذا هو الكود :
<!-- Design Code -->
<h4 style="text-align: center">Inserting new data</h4>
<table cellpadding="5" cellspacing="0" border="0" style="border: 1px solid #000; width: 330px; margin: 10px auto;">
<tr>
<td>Number of Rows: </td>
<td><asp:TextBox ID="numberOfRowsTextBox" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td style="text-align: right;"><asp:Button ID="insertButton" runat="server" Text="Submit" OnClick="insertButton_Click" /></td>
</tr>
<tr>
<td colspan="2" style="font-size: 10px;">
<asp:Label ID="statusLabel" runat="server" />
</td>
</tr>
</table>
// Code Behind
protected void insertButton_Click(object source, EventArgs e)
{
using (SqlConnection con = new SqlConnection(
ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString))
{
SqlTransaction trans = null;
try
{
con.Open();
trans = con.BeginTransaction();
int rowCount = int.Parse(numberOfRowsTextBox.Text);
for (int i = 0; i < rowCount; i++)
{
SqlCommand cmd = new SqlCommand("insert into people([name]) values('Auto Entry!')", con);
cmd.Transaction = trans;
cmd.ExecuteNonQuery();
}
trans.Commit();
statusLabel.Text = string.Format("{0} row have/hase been inserted", rowCount);
}
catch (Exception ex)
{
if (trans != null)
if (trans.Connection.State == ConnectionState.Open)
trans.Rollback();
statusLabel.Text = ex.Message;
}
}
}أيضا سأضيف صفحة data.aspx والتي فيها سيتم عرض البيانات، وهذا الكود المتعلق بها :
<!-- Design Code -->
<h4 style="text-align: center;">
Display data</h4>
<asp:SqlDataSource ID="peopleDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:DbConnection %>"
SelectCommand="get_paged_data" SelectCommandType="StoredProcedure"
onselected="peopleDataSource_Selected">
<SelectParameters>
<asp:QueryStringParameter Name="page_index" DefaultValue="0" Type="Int32" QueryStringField="i" />
<asp:Parameter Name="number_of_rows" DefaultValue="15" Type="Int32" />
<asp:Parameter Name="row_count" Direction="Output" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
<div style="margin: 0 auto; width: 500px; border: 1px solid #07f">
<asp:ListView ID="peopleListView" runat="server" DataSourceID="peopleDataSource" ItemPlaceholderID="itemPlaceHolder">
<LayoutTemplate>
<ul>
<asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
</ul>
<p id="pager" runat="server" style="padding: 3px; word-wrap: break-word;" />
<p style="text-align: right; padding: 3px;" id="rowCount" runat="server"></p>
</LayoutTemplate>
<ItemTemplate>
<li>
<%# Eval("id") %> : <%# Eval("name") %> <p style="display: inline; font-size: 8px; color: #77f;">(<%# Eval("entry_date") %>)</p>
</li>
</ItemTemplate>
</asp:ListView>
</div>
// Code Behind
protected void peopleDataSource_Selected(object sender, SqlDataSourceStatusEventArgs e)
{
HtmlContainerControl htmlControl =
(HtmlContainerControl)peopleListView.FindControl("rowCount");
int rowCount = int.Parse(e.Command.Parameters["@row_count"].Value.ToString());
if (htmlControl != null)
htmlControl.InnerHtml =
string.Format("Record(s) Count: {0}", rowCount);
RenderPager(rowCount);
}
protected void RenderPager(int rowCount)
{
int pages = rowCount / 15;
int currentPage = Request["i"] != null ? int.Parse(Request["i"]) : 0;
string pattern = "<a href='data.aspx?i={0}'>{1}</a>";
string html = null;
for (int i = 0; i < pages; i++)
html += (i != currentPage ? string.Format(pattern, i, i + 1) : (i + 1).ToString()) + " ";
HtmlContainerControl htmlControl = (HtmlContainerControl)peopleListView.FindControl("pager");
if (htmlControl != null)
htmlControl.InnerHtml = html;
}في المفرقات ستجدون المشروع كامل
أتمنى للجميع التوفيق والنجاح
