C# 填充下拉列表的最快方法

C# 填充下拉列表的最快方法,c#,asp.net,C#,Asp.net,我刚刚用webforms和C和我的asp.net项目接管了一个项目。我的页面加载时间非常慢,我认为这是由于正在进行的多个数据库调用造成的,但是我不知道如何以任何不同的方式进行。例如,我有一个页面包含3个不同的dropdownlists每个dropdownlist都填充在page\u Load()事件处理程序中,但所有3个都有自己的数据库调用 下面是pseducode以显示所使用的方法。完成这样的事情的正确方法是什么 namespace CEDS { public partial class BB

我刚刚用
webforms
C
和我的
asp.net
项目接管了一个项目。我的页面加载时间非常慢,我认为这是由于正在进行的多个数据库调用造成的,但是我不知道如何以任何不同的方式进行。例如,我有一个页面包含3个不同的
dropdownlists
每个
dropdownlist
都填充在
page\u Load()
事件处理程序中,但所有3个都有自己的数据库调用

下面是pseducode以显示所使用的方法。完成这样的事情的正确方法是什么

namespace CEDS
{
public partial class BBLL : System.Web.UI.UserControl
{
    private DataSet DS = new DataSet();
    private C2 _C2 = new C2();

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            GetDataForDropDown1();
            GetDataForDropDown2();
            GetDataForDropDown3();
        }
    }
    private void GetDataForDropDown1()
    {   
        DS = _C2.GetDataForDropDown1();
        this.gv1.DataSource = DS;
        this.gv1.DataBind();  
        this.gv1.Visible = true;            
    }
    private void GetDataForDropDown2()
    {   
        DS = _C2.GetDataForDropDown2();
        this.gv2.DataSource = DS;
        this.gv2.DataBind(); 
        this.gv2.Visible = true;            
    }
    private void GetDataForDropDown3()
    {   
        DS = _C2.GetDataForDropDown3();
        this.gv3.DataSource = DS;
        this.gv3.DataBind(); 
        this.gv3.Visible = true;            
    }

}
public class C2
{
    private DataSet DS = new DataSet();
    private DatabaseAccessLayer DAL = new DatabaseAccessLayer();

    public DataSet GetDataForDropDown1()
    {
        DS = new DataSet(); 
        DAL.SqlQueryBuilder = new StringBuilder();
        DAL.SqlQueryBuilder.Append("exec dbo.RunStoredProcedure1 ");
        DS = DAL.ExecuteSqlQuery(databaseConnection, DAL.SqlQueryBuilder.ToString());
        return DS;
    }
    public DataSet GetDataForDropDown2()
    {
        DS = new DataSet(); 
        DAL.SqlQueryBuilder = new StringBuilder();
        DAL.SqlQueryBuilder.Append("exec dbo.RunStoredProcedure2 ");
        DS = DAL.ExecuteSqlQuery(databaseConnection, DAL.SqlQueryBuilder.ToString());
        return DS;
    }
    public DataSet GetDataForDropDown3()
    {
        DS = new DataSet(); 
        DAL.SqlQueryBuilder = new StringBuilder();
        DAL.SqlQueryBuilder.Append("exec dbo.RunStoredProcedure3 ");
        DS = DAL.ExecuteSqlQuery(databaseConnection, DAL.SqlQueryBuilder.ToString());
        return DS;
    }
}
public class DatabaseAccessLayer
{
    public DataSet ExecuteSqlQuery(string connectionString, string sqlQuery)
    {
        try
        {            
            _connectionString = System.Configuration.ConfigurationManager.AppSettings[connectionString].ToString();       
            _sqlDatabaseConnection = new SqlConnection(_connectionString);
            _sqlCommand = new SqlCommand(sqlQuery, _sqlDatabaseConnection);
            _sqlDatabaseConnection.Open();
            _sqlCommand.CommandTimeout = 0;   
            _dataSet = new DataSet();
            _sqlDataAdapter = new SqlDataAdapter(_sqlCommand);            
            _sqlDataAdapter.Fill(_dataSet, "Data");
            return _dataSet;
        }
        catch (Exception exception) { throw exception; }
        finally
        {
            _sqlDatabaseConnection.Close();
            _sqlCommand.Dispose();
            _sqlDataAdapter.Dispose();
        }
    }
}

}你应该能够做到

Parallel.Invoke(GetDataForDropDown1, GetDataForDropDown2, GetDataForDropDown3);
所以,至少在你开始等待第二次和第三次之前,你不会等待第一次完成


让一个存储过程返回所有三个记录集可能更有效,这样数据库连接和检索往返只进行一次。但这可能意味着您必须更改数据层代码。

您应该可以这样做

Parallel.Invoke(GetDataForDropDown1, GetDataForDropDown2, GetDataForDropDown3);
Page_Load()
{
  var t1 = GetDataForDropDown1();
  var t2 = GetDataForDropDown2();
  var t3 = GetDataForDropDown3();
  await Task.WhenAll(t1, t2, t3);
  PopulateDD1();
  PopulateDD2();
  PopulateDD3();
}
async Task GetDataForDropDown1()
{
  SqlQuery
  Call To Database Access Layer
  await Execute Stored Procedure
  Store Returned Result In Dataset  
}
async Task GetDataForDropDown2()
{
  SqlQuery
  Call To Database Access Layer
  await Execute Stored Procedure
  Store Returned Result In Dataset  
}
async Task GetDataForDropDown3()
{
  SqlQuery
  Call To Database Access Layer
  await Execute Stored Procedure
  Store Returned Result In Dataset  
}
所以,至少在你开始等待第二次和第三次之前,你不会等待第一次完成


让一个存储过程返回所有三个记录集可能更有效,这样数据库连接和检索往返只进行一次。但这可能意味着您必须更改数据层代码。

更好的方法可能是这样,试试看

Page_Load()
{
  var t1 = GetDataForDropDown1();
  var t2 = GetDataForDropDown2();
  var t3 = GetDataForDropDown3();
  await Task.WhenAll(t1, t2, t3);
  PopulateDD1();
  PopulateDD2();
  PopulateDD3();
}
async Task GetDataForDropDown1()
{
  SqlQuery
  Call To Database Access Layer
  await Execute Stored Procedure
  Store Returned Result In Dataset  
}
async Task GetDataForDropDown2()
{
  SqlQuery
  Call To Database Access Layer
  await Execute Stored Procedure
  Store Returned Result In Dataset  
}
async Task GetDataForDropDown3()
{
  SqlQuery
  Call To Database Access Layer
  await Execute Stored Procedure
  Store Returned Result In Dataset  
}
Page_Load()
{
  if(!Page.IsPostBack)
  {
     LoadData();
   }
}

LoadData()
{
// PopulateDropDown1 Code
// PopulateDropDown2 Code
// PopulateDropDown3 Code
}

如果(!Page.IsPostBack)
阻止
LoadData()
调用每次回发。

更好的方法可能是这样,试试看

Page_Load()
{
  if(!Page.IsPostBack)
  {
     LoadData();
   }
}

LoadData()
{
// PopulateDropDown1 Code
// PopulateDropDown2 Code
// PopulateDropDown3 Code
}

如果(!Page.IsPostBack)
阻止
LoadData()
调用每次回发。

您应该打开SQL探查器并加载页面,然后隔离每个SqlQuery并将其复制/粘贴到SSM中。查询执行时间将让您看到在这些查询上花费了多少时间,而不是在.Net内部(尽管此规则有一些例外)。如果同时打开执行计划,它将在数据上缺少索引时发出警告。如何打开SQL Profiler?我刚刚注意到您有SqlQuery和一个存储过程。SQL Profiler是一个单独的工具,可以与SQL Server一起安装。如果您没有,您将不得不尝试编写SQL代码以直接在SSMS中运行过程,例如,
exec myproc@param1=foo,@param2=bar
您可以用一个(简短的)示例更新您的代码吗?这样我就知道您没有在ASP.NET中创建过程,这会很糟糕?!您应该打开SQL Profiler并加载页面,然后隔离每个SqlQuery并将它们复制/粘贴到SSM中。查询执行时间将让您看到在这些查询上花费了多少时间,而不是在.Net内部(尽管此规则有一些例外)。如果同时打开执行计划,它将在数据上缺少索引时发出警告。如何打开SQL Profiler?我刚刚注意到您有SqlQuery和一个存储过程。SQL Profiler是一个单独的工具,可以与SQL Server一起安装。如果您没有,您将不得不尝试编写SQL代码以直接在SSMS中运行过程,例如,
exec myproc@param1=foo,@param2=bar
您可以用一个(简短的)示例更新您的代码吗?这样我就知道您没有在ASP.NET中创建过程,这会很糟糕?!只是出于兴趣,如果列表是嵌套的,那么第一个必须在第二个开始加载之前加载其值,这种方法仍然有效吗?只是出于兴趣,如果列表是嵌套的,那么第一个必须在第二个开始加载之前加载其值,这种方法仍然有效吗?