2012-10-12 64 views
2

我很好奇這是爲什麼。我就遇到了這個情況今天早些時候SqlConnection不能在另一個SqlConnection的'using'子句中打開嗎?

using (SqlConnection oConn = new SqlConnection(ConnectionString)) 
{ 
    using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn)) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.AddWithValue("@PortalId", portalId); 
     cmd.Parameters.AddWithValue("@Description", description); 
     cmd.Parameters.AddWithValue("@StartDate", start); 
     cmd.Parameters.AddWithValue("@EndDate", end); 

     try 
     { 
      oConn.Open(); 
      cmd.ExecuteNonQuery(); 
     } 
     catch (SqlException ex) 
     { 
      throw ex; 

     } 
    } 
} 

//Get the new set of ExpenseCycles for binding 
ExpenseCycle cycle = new ExpenseCycle(ConnectionString); 
return cycle.GetExpenseCycles(portalId); 

// ^^ this works just fine. The GetExpenseCycles call will basically set up the structure above with using SqlConnection and using SqlCommand 

using (SqlConnection oConn = new SqlConnection(ConnectionString)) 
{ 
    using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn)) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.AddWithValue("@PortalId", portalId); 
     cmd.Parameters.AddWithValue("@Description", description); 
     cmd.Parameters.AddWithValue("@StartDate", start); 
     cmd.Parameters.AddWithValue("@EndDate", end); 

     try 
     { 
      oConn.Open(); 
      cmd.ExecuteNonQuery(); 
     } 
     catch (SqlException ex) 
     { 
      throw ex; 

     } 

     //Get the new set of ExpenseCycles for binding 
     ExpenseCycle cycle = new ExpenseCycle(ConnectionString); 
     return cycle.GetExpenseCycles(portalId); 

     //This didn't work. The INSERT statement was successful, but it was bringing back old entries, and did not include the newest one that was just inserted 
    } 
} 

底部代碼塊最初我有什麼,我的測試環境返回數僅爲1,但有2條記錄在數據庫中。它沒有獲取新插入的記錄。

GetExpenseCycles的基本代碼如下:

using (SqlConnection oConn = new SqlConnection(ConnectionString)) 
{ 
    using (SqlCommand cmd = new SqlCommand("IC_Expense_GetExpenseCyclesByPortal",oConn)) 
    { 
     oConn.Open(); 
     using (SqlDataReader sdr = cmd.ExecuteReader()) 
     { 
      //Read List<expensecycle> here 
     } 
    } 
} 

任何想法,爲什麼?沒有例外拋出。

+0

Hrrrm,你認爲只是有一個通用的拋出會拋出別的不是'SqlException'? – dgarbacz

+0

除非你打算用'SqlException'做一些事情,否則我不會費心去重新拋出它。 – James

+0

你在代碼中有一個return語句,所以很明顯只有第一個插入被執行 –

回答

3

拋出沒有異常,所以沒有任何錯誤......我懷疑連接

在連接不重疊的第一個場景的隔離級別。

ExpenseCycle()使用連接字符串,我可以安全地假定它啓動一個新的連接。

在第二個例子(問題的情況下)的連接確實重疊:

如果隔離級是例如讀取 - 提交和「包封」連接尚未穩定其寫入(提交)的新連接不接受更改,在這種情況下,插入。

可能的解決方案或事物嘗試: 1.檢查連接 2.將連接,而不是ConnectionString,以ExpenseCycle()(這是一個更好的做法太恕我直言)

1

在隔離級別您可能有一個環境事務有效(如果在事務範圍內調用代碼塊,則新連接將自動加入該事務。使用TransactionScope class,您可以獲得該事務的句柄並在第二次調用之前提交它。

另外它看起來像你的第二個調用是在命令的usi範圍內ng塊。移動它的存在之外可能足以解決您的問題

using (SqlConnection oConn = new SqlConnection(ConnectionString)) 
{  
    using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn))  
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.AddWithValue("@PortalId", portalId); 
     cmd.Parameters.AddWithValue("@Description", description); 
     cmd.Parameters.AddWithValue("@StartDate", start); 
     cmd.Parameters.AddWithValue("@EndDate", end);   
     try 
     { 
     oConn.Open(); 
     cmd.ExecuteNonQuery(); 
     } 
     catch (SqlException ex) 
     { 
     throw ex; 
     } 
    }//close the SqlCommand 
    //Get the new set of ExpenseCycles for binding 
    ExpenseCycle cycle = new ExpenseCycle(ConnectionString); 
    return cycle.GetExpenseCycles(portalId); 
    //This might fix your problem. 
} 

另一種選擇是移動第二呼叫使用首先使用塊外,像這樣

bool insertSuccessful; 
using (SqlConnection oConn = new SqlConnection(ConnectionString)) 
{  
    using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn))  
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.AddWithValue("@PortalId", portalId); 
     cmd.Parameters.AddWithValue("@Description", description); 
     cmd.Parameters.AddWithValue("@StartDate", start); 
     cmd.Parameters.AddWithValue("@EndDate", end);   
     try 
     { 
     oConn.Open(); 
     cmd.ExecuteNonQuery(); 
     insertSuccessful=true; 
     } 
     catch (SqlException ex) 
     { 
     insertSuccessful=false 
     throw ex; 
     } 
    }//close the SqlCommand 
}//close the connection 
//Get the new set of ExpenseCycles for binding 
if(insertSuccessful) 
{ 
    ExpenseCycle cycle = new ExpenseCycle(ConnectionString); 
    return cycle.GetExpenseCycles(portalId); 
} 

我想第一個塊應該解決你的問題。如果不是第二個肯定應該。