簡體   English   中英

在C#中調用多個“SQL DataReader”的正確方法是什么?

[英]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包裝SqlConnectionSqlCommand 這將強制在使用塊時保留對象的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接口。 在您的示例中,您還可以使用SqlConnectionSqlCommand使用代碼塊。

使用'使用',您無需手動關閉和處理。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM