[英]What is the proper way of calling multiple “SQL DataReader”s in C#?
我調用ExecuteReader();
要獲取數據,那么我需要使用另一個查詢獲取另一個數據。 我的結構一直都是這樣的:
class SomeClass
{
public static void Main(String[] args)
{
SqlConnection sqlConn = new SqlConnection();
sqlConn.ConnectionString = "some connection string"
SqlCommand SQLCmd = new SqlCommand();
SQLCmd.CommandText = "some query";
SQLCmd.Connection = sqlConn;
sqlConn.Open();
sqlReader = SQLCmd.ExecuteReader();
while (sqlReader.Read())
{
//some stuff here
}
sqlReader.Dispose();
sqlReader.Close();
sqlConn.Close();
SQLCmd.CommandText = "another query";
sqlConn.Open();
sqlReader = SQLCmd.ExecuteReader();
while (sqlReader.Read())
{
//some other stuff here
}
sqlReader.Dispose();
sqlReader.Close();
sqlConn.Close();
}
}
它們共享相同的連接字符串。 他們還能分享什么? 他們可以共享相同的sqlConn.Open();
? 什么是資源分配和避免錯誤的正確方法?
BTW它的工作原理。 提前致謝。
這就是我寫所有這些的方式:
class SomeClass
{
public static void Main(String[] args)
{
using (SqlConnection sqlConn = new SqlConnection("some connection string"))
{
sqlConn.Open();
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some other stuff here
}
}
}
}
}
using
語句處理塊完成時處理項目。 至於共享內容,您可以在命令之間保持連接打開。
處理所有這一切的最重要的事情就是連接,但是如果一個項目是IDisposable
而不管它在后台實際做了什么(由於它是一個實現細節,它可能會改變),我傾向於尊重using
聲明。 。
不要忘記,單個命令和單個閱讀器中還有多個活動結果集(如本答案中所示) ,您可以將閱讀器推進到下一個結果集。
return connection.Query<T>(procedureName, param, commandType: CommandType.StoredProcedure);
使用Dapper ;-)
正如我的評論中提到的那樣 - 如果可能的話,將兩個查詢合並為一個然后(如果它仍然產生多個結果集),使用NextResult
繼續前進。
竊取亞當的結構 ,但隨着這種變化:
class SomeClass
{
public static void Main(String[] args)
{
using (SqlConnection sqlConn = new SqlConnection("some connection string"))
{
sqlConn.Open();
using (SqlCommand comm = new SqlCommand("some query; some other query;", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
if(sqlReader.NextResult())
{
while (sqlReader.Read())
{
//some other stuff here
}
}
}
}
}
}
正確的方法是using
-statements包裝SqlConnection
和SqlCommand
。 這將強制在使用塊時保留對象的Dispose
,即使拋出異常也是如此。 (當前代碼不是這種情況。)
有點像
using(var cnn = new SqlConnection("connectionstring")){
cnn.Open();
using(var cmd = new SqlCommand("SELECT 1")){
var reader = cmd.ExecuteReader();
while(reader.Read()) { /* doStuff */ }
}
}
無論何種方法, Close
/ Dispose
都不會實際關閉連接,因為連接設置非常昂貴。 它只會將連接返回到連接池,並允許其他命令/讀者使用它。
為了管理資源,您可以使用using
像在如圖所示...
SQLCmd.CommandText = "some query";
SQLCmd.Connection = sqlConn;
sqlConn.Open();
//using will dispose reader automatically.
using(sqlReader = SQLCmd.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
//sqlReader.Dispose();
//sqlReader.Close();
//sqlConn.Close();
SQLCmd.CommandText = "another query";
//no need to open connection again.
// sqlConn.Open();
// sqlReader = SQLCmd.ExecuteReader();
using(sqlReader = SQLCmd.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
//sqlReader.Dispose();
//sqlReader.Close();
//sqlConn.Close();
您可以使用using
僅適用於已經實現了這些類IDispose
接口。 在您的示例中,您還可以使用SqlConnection
和SqlCommand
使用代碼塊。
使用'使用',您無需手動關閉和處理。
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("spTest", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@employeeid", employeeID));
command.CommandTimeout = 5;
command.ExecuteNonQuery();
}
每次需要時打開一個新連接是最佳實踐。 ADO.net使用連接池來進行連接。 http://msdn.microsoft.com/it-it/library/8xx3tyca(v=vs.110).aspx
不要忘記你的try catch語句:)
class SomeClass
{
public static void Main(String[] args)
{
using (SqlConnection sqlConn = new SqlConnection("some connection string"))
{
try{
sqlConn.Open();
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some other stuff here
}
}
}
catch()
{
// Do exception catching here or rollbacktransaction if your using begin transact
}
finally
{
sqlConn.Close();
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.