2016-04-13 149 views
-1

首先,我想提一下,我不是一個編碼器。基本上,我從零開始學習C#,我並不介意。優化C#代碼/硬編碼

這是我的代碼試圖完成的一點背景。

我有一個級聯DDL1的數據庫名稱。當用戶選擇數據庫名稱時,他們需要爲日期範圍選擇DDL2(使用「some」參數運行不同的查詢)。

它運行的查詢涉及連接來自不同數據庫的2個表(我認爲這是我所遇到的總體問題)。

我可以讓代碼工作,但它看起來非常乏味,而且我確信硬編碼是不受歡迎的,除非必要。我做了一些研究,看起來我需要使用動態SQL來對存儲過程中的數據庫名稱進行參數化,我不願意使用它。

所以,總結。對於每個數據庫名稱和每個日期範圍,我需要分別對它們進行硬編碼。這將是每個數據庫總共4個代碼塊。如果數據全部存在於1個表中,我就不會有這個問題。

再一次,我是相當新的,幾乎是一個初學者。請讓我知道是否可以優化代碼並使其更高效,因爲就目前而言,它看起來像編碼不好。

的代碼如下提供,感謝:

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) 
{ 

{ 
    DataTable dt = new DataTable(); 
    SqlDataAdapter Adpt; 

    if (DropDownList1.SelectedValue == string.Empty & DropDownList2.SelectedValue == string.Empty) 
    { 
    } 

    if (DropDownList1.SelectedItem.Text == "ytd" & DropDownList2.SelectedValue == "db1") 
     using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["db1ConnectionString"].ConnectionString)) 
     { 
      SqlCommand cmd = new SqlCommand("select sum(column1) from table1 inner join db2.dbo.table2 on db2.dbo.table2.ID = db1.dbo.table3.id where somecolumn = @somecolumn and Date <= GetDate() AND YEAR(Date) = year(GetDate()) AND Status = @Status", con); 
      cmd.Parameters.AddWithValue("@somecolumn", DropDownList2.SelectedValue); 
      cmd.Parameters.AddWithValue("@status", "done"); 
      Adpt = new SqlDataAdapter(cmd); 
      new SqlDataAdapter(cmd).Fill(dt); 
     } 

    if (DropDownList1.SelectedItem.Text == "yesterday" & DropDownList2.SelectedValue == "db1") 
     using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["db1ConnectionString"].ConnectionString)) 
     { 
      SqlCommand cmd = new SqlCommand("select sum(column1) from table1 inner join db2.dbo.table2 on db2.dbo.table2.ID = db1.dbo.table3.id where somecolumn = @somecolumn and Date >= DATEADD(DAY, DATEDIFF(DAY, 1, GETDATE()), 0) AND Date <= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) AND Status = @Status", con); 
      cmd.Parameters.AddWithValue("@somecolumn", DropDownList2.SelectedValue); 
      cmd.Parameters.AddWithValue("@status", "done"); 
      Adpt = new SqlDataAdapter(cmd); 
      new SqlDataAdapter(cmd).Fill(dt); 

    //if same code, different database 
     { 
     } 

    //if same code, different database 
     { 
     } 

    //else if same code, different database   
     { 
     } 

    GridView1.DataSource = dt; 
    GridView1.DataBind(); 

} 


protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    { 
     if (DropDownList2.SelectedIndex == 0) 
     { 
      DropDownList1.SelectedIndex = 0; 
      DropDownList1.Enabled = false; 
     } 
     else 
     { 
      DropDownList1.Enabled = true; 
      DropDownList1.SelectedIndex = 0; 
     } 

    } 
} 

}

回答

1

的關鍵在於良好的編程是可能的情況下消除冗餘。如果你的大部分代碼都是相同或非常相似的數字,那麼怎麼不重複自己。

例如你的代碼的快速重構會是這個樣子:

var selectStatement = "select sum(column1) from table1 inner join db2.dbo.table2 on db2.dbo.table2.ID = db1.dbo.table3.id where somecolumn = @somecolumn " 
string whereClause; 

if (DropDownList2.SelectedValue == "db1") 
{ 
    if (DropDownList1.SelectedItem.Text == "ytd") 
    { 
     whereClause = "and Date <= GetDate() AND YEAR(Date) = year(GetDate()) AND Status = @Status"; 
    } 
    else if (DropDownList1.SelectedItem.Text == "yesterday") 
    { 
     whereClause = "and Date >= DATEADD(DAY, DATEDIFF(DAY, 1, GETDATE()), 0) AND Date <= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) AND Status = @Status" 
    } 
} 

//etc 

SqlCommand cmd = new SqlCommand(selectStatement + whereClause, con); 
cmd.Parameters.AddWithValue("@somecolumn", DropDownList2.SelectedValue); 
cmd.Parameters.AddWithValue("@status", "done"); 
Adpt = new SqlDataAdapter(cmd); 
new SqlDataAdapter(cmd).Fill(dt); 

GridView1.DataSource = dt; 
GridView1.DataBind(); 

還有改善仍有較大空間,雖然。您可以重新組織whereClause,以便狀態只出現在一個地方。您還應該考慮使用switch語句而不是if語句的大塊。

至於硬編碼。完成的狀態有點奇怪。如果它將被「完成」,那麼總是使用select語句的一部分而不是param。像你一樣編寫內聯sql不一定是壞事。你有你的查詢參數化,以避免SQL注入攻擊,這是很好的。

編輯: 改變數據庫的一種方法是使用String.Format,它將用該索引的變量替換{#}標籤。

var sourceDb = "db1"; 
var targetDb = "db2"; 
var selectStatement = string.Format("select sum(column1) from table1 inner join {0}.dbo.table2 on {0}.dbo.table2.ID = {1}.dbo.table3.id where somecolumn = @somecolumn ", targetDb, sourceDb); 

看你的代碼,你又可能要移動內部分配這些數據庫變量您如果塊並走向結束的selectStatement聲明。

+0

感謝您的幫助/提示。是否可以參數化數據庫名稱?:db2.dbo.table2.ID = db1.dbo.table3.id上的內部連接db2.dbo.table2。我只需要在db1上傳遞不同的數據庫名稱。這似乎是我的主要問題之一 –

+0

當然有一種方法。我會編輯我的帖子 –

+0

呃,是啊!感謝所有投票的人。我問的只是看能否優化它。我做了我的研究,我沒有要求任何人重寫代碼。 –