优化ASP.NET GridView数据展示与分页,解决加载缓慢问题
ASP.NET GridView 数据分页与性能优化方案
当前使用GridView结合SqlDataSource展示数据时,SqlDataSource会一次性查询所有数据库条目,导致页面加载缓慢。以下是针对分页优化及性能提升的具体实现方案:
一、前端代码修改(ASPX)
1. 启用GridView分页并配置主键映射
修改GridView控件,启用分页功能,指定每页显示条数,同时设置DataKeyNames存储核心主键字段,避免依赖单元格索引取值的潜在问题;同时配置SqlDataSource支持分页,确保仅加载当前页数据。
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:con %>" SelectCommand="SELECT [Client_tbl].[client_fullname],[Ticket_tbl].[client_phone],[Client_tbl].[client_email],[Client_tbl].[client_company],[Client_tbl].[client_id_num],[Client_tbl].[client_tax_num],[Ticket_tbl].[ticket_category],[Ticket_tbl].[ticket_shortdetails],[Ticket_tbl].[ticket_details],[Ticket_tbl].[user_fullname],[Ticket_tbl].[user_branch],[ticket_date], [Ticket_tbl].[ticket_id] FROM [Ticket_tbl] INNER JOIN [Client_tbl] ON [Ticket_tbl].[client_phone] = [Client_tbl].[client_phone] ORDER BY [Ticket_tbl].[ticket_id] DESC" EnablePaging="True" SelectCountCommand="SELECT COUNT(*) FROM [Ticket_tbl] INNER JOIN [Client_tbl] ON [Ticket_tbl].[client_phone] = [Client_tbl].[client_phone]"> </asp:SqlDataSource> <asp:GridView ID="GridView1" runat="server" class="table table-bordered table-striped" AutoGenerateColumns="False" DataSourceID="SqlDataSource2" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" AllowPaging="True" PageSize="10" DataKeyNames="ticket_id,client_phone"> <Columns> <asp:CommandField ShowSelectButton="True" /> <asp:BoundField DataField="client_fullname" HeaderText="اسم العميل" SortExpression="client_fullname" /> <asp:BoundField DataField="client_phone" HeaderText="التليفون" SortExpression="client_phone" /> <asp:BoundField DataField="client_email" HeaderText="الإيميل" SortExpression="client_email" ItemStyle-CssClass="hidden" HeaderStyle-CssClass="hidden" /> <asp:BoundField DataField="client_company" HeaderText="الشركة" SortExpression="client_company" /> <asp:BoundField DataField="client_id_num" HeaderText="رقم البطاقة" SortExpression="client_id_num" ItemStyle-CssClass="hidden" HeaderStyle-CssClass="hidden" /> <asp:BoundField DataField="client_tax_num" HeaderText="رقم التسجيل الضريبى" SortExpression="client_tax_num" ItemStyle-CssClass="hidden" HeaderStyle-CssClass="hidden" /> <asp:BoundField DataField="ticket_category" HeaderText="القسم" SortExpression="ticket_category" /> <asp:BoundField DataField="ticket_shortdetails" HeaderText="مختصر التفاصيل" SortExpression="ticket_shortdetails" /> <asp:BoundField DataField="ticket_details" HeaderText="التفاصيل" SortExpression="ticket_details" ItemStyle-CssClass="hidden" HeaderStyle-CssClass="hidden" /> <asp:BoundField DataField="user_fullname" HeaderText="المستخدم" SortExpression="user_fullname" /> <asp:BoundField DataField="user_branch" HeaderText="الفرع" SortExpression="user_branch" /> <asp:BoundField DataField="ticket_date" HeaderText="التاريخ" SortExpression="ticket_date" /> </Columns> <PagerSettings Mode="NumericFirstLast" PageButtonCount="5" /> </asp:GridView>
核心配置说明:
EnablePaging="True":开启SqlDataSource分页支持,仅查询当前页所需数据SelectCountCommand:提供总记录数查询,用于生成分页导航控件AllowPaging="True":开启GridView分页功能PageSize="10":设置每页显示10条数据(可按需调整)DataKeyNames:存储ticket_id和client_phone作为主键,用于后续可靠获取数据PagerSettings:优化分页控件样式,提升用户体验
二、后台代码优化(ASPX.CS)
原代码依赖单元格索引取值,当列顺序调整时会导致错误,改为通过DataKeys和SelectedRow.DataItem获取数据,或直接通过主键重新查询数据库(更安全):
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e) { // 从DataKeys获取主键 int ticketId = Convert.ToInt32(GridView1.SelectedDataKey["ticket_id"]); string clientPhone = GridView1.SelectedDataKey["client_phone"].ToString(); // 方式1:直接从SelectedRow的DataItem获取绑定数据(需确保GridView ViewState启用) var row = GridView1.SelectedRow.DataItem as System.Data.DataRowView; if (row != null) { client_fullnameTextBox2.Text = row["client_fullname"].ToString(); client_phoneTextBox2.Text = row["client_phone"].ToString(); client_emailTextBox2.Text = string.IsNullOrEmpty(row["client_email"].ToString()) ? "" : row["client_email"].ToString(); client_companyTextBox2.Text = string.IsNullOrEmpty(row["client_company"].ToString()) ? "" : row["client_company"].ToString(); client_id_numTextBox2.Text = string.IsNullOrEmpty(row["client_id_num"].ToString()) ? "" : row["client_id_num"].ToString(); client_tax_numTextBox2.Text = string.IsNullOrEmpty(row["client_tax_num"].ToString()) ? "" : row["client_tax_num"].ToString(); ticket_categoryDropDownList2.SelectedValue = row["ticket_category"].ToString(); ticket_shortdetailsTextBox2.Text = row["ticket_shortdetails"].ToString(); ticket_detailsTextArea2.InnerText = string.IsNullOrEmpty(row["ticket_details"].ToString()) ? " " : row["ticket_details"].ToString(); } // 方式2:通过主键重新查询数据库(更可靠,适合关闭ViewState场景) // using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["con"].ConnectionString)) // { // string query = "SELECT [Client_tbl].[client_fullname],[Client_tbl].[client_email],[Client_tbl].[client_company],[Client_tbl].[client_id_num],[Client_tbl].[client_tax_num],[Ticket_tbl].[ticket_category],[Ticket_tbl].[ticket_shortdetails],[Ticket_tbl].[ticket_details] FROM [Ticket_tbl] INNER JOIN [Client_tbl] ON [Ticket_tbl].[client_phone] = [Client_tbl].[client_phone] WHERE [Ticket_tbl].[ticket_id] = @TicketId"; // SqlCommand cmd = new SqlCommand(query, conn); // cmd.Parameters.AddWithValue("@TicketId", ticketId); // conn.Open(); // SqlDataReader reader = cmd.ExecuteReader(); // if (reader.Read()) // { // // 赋值逻辑同上 // } // conn.Close(); // } mymodal.Visible = true; }
说明:
- 方式1利用
DataItem直接获取绑定数据,无需依赖单元格索引,稳定性更高 - 方式2通过主键重新查询数据库,适合关闭ViewState的场景,可减少页面体积并确保数据最新
三、额外性能优化建议
- 数据库索引优化:为
Ticket_tbl.client_phone、Client_tbl.client_phone和Ticket_tbl.ticket_id字段添加非聚集索引,大幅提升联表查询和排序速度 - 延迟加载隐藏字段:初始查询仅返回GridView显示的字段,当用户选中行时,再通过主键查询隐藏字段(如
client_email、ticket_details等),减少初始数据传输量 - 关闭不必要的ViewState:若无需GridView保持状态,可设置
EnableViewState="False",进一步减小页面体积
内容的提问来源于stack exchange,提问作者Alfahd Steel
相关产品推荐
相关产品推荐

