2011-05-16 90 views
1

我在查詢上運行DbDataReader以刪除下拉列表中的項目(如果它們已附加到特定提交中),並且我不斷收到錯誤,告訴我該閱讀器已關閉。看不出爲什麼我的讀者在這裏被視爲封閉。我錯過了什麼?無法嘗試打電話閱讀器關閉時讀取?

protected void Page_Load(object sender, EventArgs e) 
{ 

    string x = Request.QueryString["SubId"]; 
    string connectionString = System.Configuration.ConfigurationManager. 
     ConnectionStrings["MyConnectionString"].ConnectionString; 
    string displayQuery = "SELECT CustName, CustAdd, CustCity, CustState, " + 
     "CustZip FROM Customer WHERE SubId =" + x; 
    string broQuery = "SELECT EntityType FROM Broker WHERE SubId =" + x; 
    string ddlQuery = "SELECT ProductId FROM SubmissionProducts " + 
     "WHERE SubmissionId =" + x; 
    using (SqlConnection displayConn = new SqlConnection(connectionString)) 
    { 
     displayConn.Open(); 
     SqlCommand DlistCmd = new SqlCommand(ddlQuery, displayConn); 

     using (SqlDataReader Ddldr = DlistCmd.ExecuteReader()) 
     { 
      while (Ddldr.Read()) 
      { 

       switch (Ddldr.GetInt32(0)) 
       { 
        case 1: 
         DdlProductList.Items.RemoveAt(1); 
         break; 
        case 2: 
         DdlProductList.Items.RemoveAt(2); 
         break; 
        case 3: 
         DdlProductList.Items.RemoveAt(3); 
         break; 
        case 4: 
         DdlProductList.Items.RemoveAt(4); 
         break; 
        case 5: 
         DdlProductList.Items.RemoveAt(5); 
         break; 
        case 6: 
         DdlProductList.Items.RemoveAt(6); 
         break; 
        case 7: 
         DdlProductList.Items.RemoveAt(7); 
         break; 
        default: 
         break; 
       } 
       Ddldr.Close(); 
      } 

     } 
+0

這只是一種猜測,但你的意思是在這裏執行一個DDL命令? – 2011-05-16 17:48:45

+0

我真的不喜歡這種使用'使用' – 2011-05-16 17:48:46

+8

@阿德里安:這就是'使用'....是爲... – 2011-05-16 17:50:50

回答

9

不要叫Ddldr.Close();,尤其是while內。這樣,您正在進行第一次迭代,關閉閱讀器,第二次迭代當然會在閱讀器關閉時進行。 using聲明將照顧它。只需從代碼中刪除此行。

所以:

using (SqlDataReader Ddldr = DlistCmd.ExecuteReader()) 
{ 
    while (Ddldr.Read()) 
    { 
     switch (Ddldr.GetInt32(0)) 
     { 
      ... your cases here 
      default: 
       break; 
     } 
    } 
} 

而且下面幾行:

string x = Request.QueryString["SubId"]; 
string displayQuery = "SELECT CustName, CustAdd, CustCity, CustState, CustZip FROM Customer WHERE SubId =" + x; 
string broQuery = "SELECT EntityType FROM Broker WHERE SubId =" + x; 
string ddlQuery = "SELECT ProductId FROM SubmissionProducts WHERE SubmissionId =" + x; 

臭像一堆s..t的。你應該使用參數化查詢,絕對不要寫這樣的代碼,否則你的應用程序將很容易被SQL注入。每次在編寫SQL查詢時使用字符串連接時,警報都會響起,告訴您您做錯了。

所以在這裏談到這樣做的正確方法:

protected void Page_Load(object sender, EventArgs e) 
{ 
    string x = Request.QueryString["SubId"]; 
    string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; 
    using (var conn = new SqlConnection(connectionString)) 
    using (var cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = "SELECT ProductId FROM SubmissionProducts WHERE SubmissionId = @SubmissionId"; 
     cmd.Parameters.AddWithValue("@SubmissionId", x) 

     using (var reader = cmd.ExecuteReader()) 
     { 
      while (Ddldr.Read()) 
      { 
       switch (reader.GetInt32(reader.GetOrdinal("ProductId"))) 
       { 
        ... your cases here 
        default: 
         break; 
       } 
      } 

     } 
    } 
} 
+0

謝謝Darin。我需要了解迭代的執行方式,以確認dr.close語句必須執行。這是我第一次與編碼有關,我的培訓師專門爲了簡化而禁止參數化(該網站不適用於實際部署),但是,我同意,沒有參數的查詢正在尋求注入。 – 2011-05-16 18:53:58

2

刪除此行:

Ddldr.Close(); 
+0

哈哈,當我生命中的兩個小時減少到14個字符的錯誤代碼時,就得愛它。謝謝Hogan。 – 2011-05-16 18:57:33

+1

@Brazos - 是的,這是一種痛苦。但每次它發生在我身上時,我都會爲「我不會再這樣做」的想法感到高興。 – Hogan 2011-05-16 18:58:48

相關問題