2016-03-07 41 views
1

我剛剛接管了項目,使用webformsC#以及我的asp.net項目。我的頁面加載時間非常緩慢,我認爲這是由於多個數據庫調用正在進行,但是我不知道如何以不同的方式做到這一點。例如,我有一個頁面持有3個不同的dropdownlists,每個dropdownlist都填充在Page_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(); 
     } 
    } 
} 

}

+1

您應該打開SQL事件探查器並加載頁面,然後隔離每個SqlQuery並將它們複製/粘貼到SSMS中。查詢執行時間將讓您看到在這些查詢上花了多少時間,而不是在.Net內部(儘管此規則有一些例外)。如果您也打開執行計劃,它會警告數據上是否缺少索引。 – EvilDr

+0

如何打開SQL事件探查器? –

+0

我只注意到你有SqlQuery *和*一個存儲過程。每個人在做什麼? – EvilDr

回答

2
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 
} 
2

你應該能夠做到

Parallel.Invoke(GetDataForDropDown1, GetDataForDropDown2, GetDataForDropDown3); 

那麼至少你不等待第一個完成,直到你開始等待第二次和第三。

這可能是更有效的有一個單獨的存儲過程返回所有三個的記錄,所以你的數據庫連接和檢索往返僅僅是由一次。但是這可能意味着你必須改變你的數據層代碼。

+0

出於興趣,如果列表是嵌套的,那麼第一個必須在第二個開始加載之前加載它的值,這種方法是否仍然有效? – EvilDr

1

更好的方法可能是這樣的,試試吧。

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

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

if(!Page.IsPostBack)防止LoadData()對每一個回發調用。