ASP.net通过从表中预加载数据来加速下载列表的加载

本文关键字:加载 数据 加速 下载 列表 net ASP | 更新日期: 2023-09-27 18:27:10

我有一个网格视图,它使用dropdownlist来选择员工ID,但显示姓名。

 <EditItemTemplate>
 <asp:DropDownList ID="DropDownList5" runat="server" AppendDataBoundItems="True" DataSourceID="SqlDataSourceEmployees" DataTextField="name" DataValueField="empID" SelectedValue='<%# Bind("employee") %>'>
                                <asp:ListItem></asp:ListItem>
                            </asp:DropDownList>
  </EditItemTemplate>

这很好,但SqlDataSourceEmployees在用户单击下拉列表的那一刻就被调用了,这会导致非常令人讨厌的延迟,因为据我所知,它首先会触发一个SQL命令(简单的SELECT empID,NAME FROM EMPLOYEES WHERE department=@department),然后填充列表。将dropDowList绑定到内存中已经存在的东西会更好,尤其是我不必担心页面加载后列表中的数据会发生变化。

我考虑过在PageLoad上将它加载到DataTable,然后将这样的表绑定到dropDownList,但该列表找不到上面提到的表。我甚至把DataTable作为网页的公共方法:

public partial class PlannersCurrentRoster : System.Web.UI.Page
{
 private DataSet.employeesDataTable employeesTable;
public DataSet.employeesDataTable EmployeesTable
{
    get { return employeesTable; }
    set { employeesTable = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
    DataSetTableAdapters.employeesTableAdapter TA = new DataSetTableAdapters.employeesTableAdapter();
    DataSet.employeesDataTable empTable = TA.GetDataByDepartment(lblDepartment.Text);
    EmployeesTable = empTable;

但是随后改变列表的绑定

<EditItemTemplate>
                            <asp:DropDownList ID="DropDownList5" runat="server" AppendDataBoundItems="True" DataSourceID="EmployeesTable" DataTextField="name" DataValueField="empID" SelectedValue='<%# Bind("employee") %>'>
                                <asp:ListItem></asp:ListItem>
                            </asp:DropDownList>

未能找到"EmployesTable"。

编辑:

以下是我尝试过的解决方案:

protected void GridView5_RowUpdating(object sender, GridViewUpdateEventArgs e)
{ ((DropDownList)GridView5.Rows[e.RowIndex].FindControl("DropDownList5")).DataSource = EmployeesTable;
    ((DropDownList)GridView5.Rows[e.RowIndex].FindControl("DropDownList5")).DataBind();

}

这并没有加快速度,我确信DDL仍然从SQL源获取数据(当我试图删除它时,我遇到了一个错误,指出SelevtedValue无效)

所以我试着提前一步,在编辑事件期间分配它

 protected void GridView5_RowEditing(object sender, GridViewEditEventArgs e)
{
    ((DropDownList)GridView5.FindControl("DropDownList5")).DataSource = EmployeesTable;
    ((DropDownList)GridView5.FindControl("DropDownList5")).DataBind();

}

但随后它无法找到dropdownloadlist5

编辑:我放弃了。在阅读了这篇文章之后,我简单地将SQLDataSource类型更改为DataReader,这确实提高了性能。或者可能是对我疲惫的大脑的安慰剂效应。

ASP.net通过从表中预加载数据来加速下载列表的加载

您不能按照现有的方式进行操作,因为页面一提供,employeesTable变量就会被销毁。然后,每个回发都会获得一个新实例。如果列表不是唯一的,请将其存储到缓存对象中。然后您也可以为它设置一个超时。

如果它基于页面的数据,则可以将它存储在会话中,会话可以跨页面携带它,但如果在会话中跨用户存储大量对象,则可能会降低性能。

如果它不是太大,您可以将其存储在ViewState中。然后将其序列化给客户。不利的一面是,数据可能会使发送到客户端的HTML膨胀。

在您的情况下,由于数据表似乎依赖于一个文本字段,所以最好使用viewstate。然而,在您的情况下,由于您需要知道文本值何时也发生了变化,从而可以否定数据,因此会增加复杂性。

以下是ViewState的一个粗略示例,但您也可以适应Session和Cache。

private string SelectedDepartmentText
{
    get
    {
        if(ViewState["SelectedDepartmentText"] != null)
            return ViewState["SelectedDepartmentText"].ToString();
        else
            return string.Empty;
    }
    set{ViewState["SelectedDepartmentText"] = value;}
}
public DataSet.employeesDataTable EmployeesTable
{
     get
    {
           if(!SelectedDepartmentText.Equals(lblDepartment.Text))
           {
               // if the SelectedDepartmentText isn't the same as the lblDepartment.Text, go fetch it
               DataSetTableAdapters.employeesTableAdapter TA = new DataSetTableAdapters.employeesTableAdapter();
               ViewState["EmployeesTable"] =TA.GetDataByDepartment(lblDepartment.Text);
               // save the lblDepartment.Text value to the viewstate for next time.
               SelectedDepartmentText = lblDepartment.Text;
               return ViewState["EmployeesTable"];
           }
           else
           {
               // let's see if we have something already and return it
               if(ViewState["EmployeesTable"] != null)
                   return (DataSet.employeesDataTable)ViewState["EmployeesTable"];
               else
                {
                // if we don't, let's get it, this also handles an empty string for the                     
                // lblDepartment.Text
            DataSetTableAdapters.employeesTableAdapter TA = new DataSetTableAdapters.employeesTableAdapter();
                        // store it in the viewstate
            ViewState["EmployeesTable"] =TA.GetDataByDepartment(lblDepartment.Text);
                        // and return whatever we got back
            return (DataSet.employeesDataTable)ViewState["EmployeesTable"];
                }
           }
           return null;
    }
    set{ ViewState["EmployeesTable"] = value;}
}