简体   繁体   English

ASP.net通过从表中预加载其数据来加速dropdownlist加载

[英]ASP.net Speeding up the dropdownlist load by preloading its data from table

I have a grid view that uses dropdownlist to select employees ID but displaying names. 我有一个网格视图,该视图使用下拉列表选择员工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>

This works fine, but the SqlDataSourceEmployees is called the moment user clicks on the dropdownlist, which causes quite annoying delay, since as I understand first it fires a SQL command (simple SELECT empID,NAME FROM EMPLOYEES WHERE department=@department ) and then the list is populated. 这可以正常工作,但是当用户单击下拉列表时会调用SqlDataSourceEmployees,这会引起非常烦人的延迟,因为据我所知,它会触发一个SQL命令(简单的SELECT empID,NAME FROM EMPLOYEES WHERE department=@department ),然后列表被填充。 It would be much better to bind the dropDowList to something that is already in memory, especially that I don't have to worry that the data in the list would change after page has been loaded. 将dropDowList绑定到内存中已经存在的东西会更好,尤其是我不必担心列表中的数据在页面加载后会更改。

I've thought about loading it to the DataTable on PageLoad and then binding such table to dropDownList but the list cannot find mentioned above table. 我曾考虑过将其加载到PageLoad上的DataTable中,然后将此类表绑定到dropDownList,但该列表找不到上面提到的表。 I've even put the DataTable as public method of the webpage: 我什至把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;

but then changing the bind of the list 但是然后更改列表的绑定

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

fails to find the "EmployesTable". 找不到“ EmployesTable”。

EDIT: 编辑:

Following the solution below I've tried: 按照下面的解决方案,我尝试了:

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();

} }

Which doesn't speed up things a bit, I'm sure that the DDL still takes data from SQL source (when I was trying to remove it, I had an error stating that SelevtedValue is invalid) 这样做并没有加快速度,我确定DDL仍然会从SQL源中获取数据(当我尝试删除它时,出现了一个错误,指出SelevtedValue无效)

So I've tried to assign it one step earlier, during editing event 因此,我尝试在编辑事件期间将其分配给较早的一步

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


}

but then it fails to find dropdownlist5 但是后来找不到dropdownlist5

EDIT: I give up. 编辑:我放弃了。 After reading this article I've simply changed SQLDataSource type to DataReader which indeed improved performance. 阅读本文后,我只是将SQLDataSource类型更改为DataReader,这确实提高了性能。 Or maybe its the placebo effect for my tired mind. 也许对我疲惫的头脑来说,它是安慰剂的作用。

You can't do it the way you have it since the your employeesTable variable is destroyed as soon as the page is served. 您无法以现有的方式进行操作,因为在页面被提供后,employeesTable变量将被销毁。 Each postback then gets a new instance. 然后,每个回发都会获得一个新实例。 If the list is not unique, instead store it into the Cache object. 如果列表不是唯一的,则将其存储到Cache对象中。 You can then set a timeout for it as well. 然后,您也可以为其设置超时。

If it is based on data for the page, you can either store it in session which could carry it across pages but can degrade performance if you have a large number of objects storing in session across users. 如果它基于页面的数据,则可以将其存储在会话中,这可能会跨页面携带它,但是如果您在用户之间的会话中存储了大量对象,则可能会降低性能。

If it's not too large you could store it in ViewState instead. 如果不是太大,可以将其存储在ViewState中。 It will then be serialised to the client. 然后将其序列化到客户端。 The downside is, the data can bloat the HTML sent to the client. 缺点是,数据可能会使发送给客户端的HTML膨胀。

In your case, since the datatable seems to be dependent upon the a text field, it may be better to use the viewstate. 在您的情况下,由于数据表似乎依赖于文本字段,因此使用viewstate可能更好。 In your case though, complexity is added due to the fact you need to know when the text value has changed as well so you can negate the data. 但是,在您的情况下,由于您需要知道文本值何时发生更改,因此增加了复杂性,因此您可以取反数据。

The following is a crude example of ViewState but you can also adapt for Session and the Cache. 以下是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;}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM