2017-12-10 14 views
2

これは私が時折返すものですが、まだ決定的な答えは見つかりませんでした。うまくいけば、私はそれがマイクロソフトが言語を遺産にする(冗談...ちょっと)前にそれを得るだろう...foreachループで宣言されたときのSQLDataReaderオブジェクト

これはほぼ間違っているが、これは私がSQLServerからレコードを取得してきた方法です...私は各行それをIDataRecordとして呼び出し元に渡し、SQLDataREaderオブジェクトを使用してそれを反復処理します。私は、usingステートメントで宣言されていなければ、datareaderは使用後に閉じなければならないと読んでいます。私はこれを閉じるべきですか?私のSqlDataReaderのは、このようなforeachループ内で宣言され

...

IEnumerable<IDataRecord> dataset = Select("SELECT Topic FROM Topics WHERE pti=" + pid + " and Ignore = 0"); 
foreach (SqlDataReader reader in dataset) 
{ 
    string topic = reader.GetString(0); 
    //... do something 
} 

マイデシベルコール:

public IEnumerable<IDataRecord> Select(string sql, List<SqlParameter> sparams = null) 
{ 
    using (SqlConnection cn = new SqlConnection(ConnString())) 
    { 
     cn.Open(); 

     using (SqlCommand cmd = new SqlCommand(sql, cn)) 
     { 
      if (sparams != null) 
      { 
       cmd.CommandType = CommandType.StoredProcedure; 
       cmd.Parameters.AddRange(sparams.ToArray()); 
      } 
      else 
      { 
       cmd.CommandType = CommandType.Text; 
      } 

      using (SqlDataReader rdr = cmd.ExecuteReader()) 
      { 
       if (rdr != null && rdr.FieldCount > 0) 
       { 
        while (rdr.Read()) 
        { 
         yield return rdr; 
        } 
       } 

      } 
     } 

     cn.Close(); 

    } 
} 

答えて

1

実際に閉鎖するためには何もありません。コード内のクローズ可能なリーダーオブジェクトは接続を使用するオブジェクトですが、Selectメソッドのusingステートメントによって自動的に閉じられます。

あなたのやり方はかなり珍しいと思います。あなたがメソッドのシグネチャを変更することができるしている場合は、単にcastを行うと、このようなyieldを除去することにより、List<>を返すことができます:

public List<IDataRecord> Select(string sql , List<SqlParameter> sparams = null) 
     {                   
      using (SqlConnection cn = new SqlConnection (ConnectionString))   
      {                   
       cn.Open ();               

       using (SqlCommand cmd = new SqlCommand (sql , cn))      
       {                  
        if (sparams != null)             
        {                  
         cmd.CommandType = CommandType.StoredProcedure;      
         cmd.Parameters.AddRange (sparams.ToArray ());      
        }                  
        else                 
        {                  
         cmd.CommandType = CommandType.Text;         
        }                  

        using (SqlDataReader rdr = cmd.ExecuteReader ())      
        {                  
         return rdr.Cast<IDataRecord> ().ToList ();      

        }                  
       }                  
      }                   
     } 

私は、DB接続クラスでこれをやりました。それはかなり簡単ですが、ご不明な点がございましたら、ご意見をお寄せください:

using System;                                      
using System.Collections.Generic;                                 
using System.Data;                                     
using System.Data.SqlClient;                                  
using System.Linq;                                     

namespace SqlToDb                                     
{                                         
    public class SqlClientData                                  
    {                                         
     private string connectionstring;                                

     public string ConnectionString { get => connectionstring; set => connectionstring = value; }                 

     public SqlClientData(string connection_string)                             
     {                                        
      ConnectionString = connection_string;                               
     }                                        

     public T ExecuteScalar<T>(string queryString)                             
     {                                        
      using (SqlConnection conn = new SqlConnection (ConnectionString))                        
      {                                        

       using (SqlCommand cmd = new SqlCommand (queryString , conn))                        
       {                                       
        try                                      
        {                                       
         conn.Open ();                                   
         var result = cmd.ExecuteScalar ();                              

         if (Convert.IsDBNull (result) && typeof (T).IsValueType)                        
          return default (T);           // if the db value is null, but T is a value type, set T = the default value of the type. 
         else                                     
          return (T) (result);                                 
        }                                       
        finally                                     
        {                                       
         conn.Close ();                                   
        }                                       

       }                                       

      }                                        
     }                                        

     public List<T> ExecScalarList<T>(string sql , bool exclude_nulls , bool replace_null_with_default)                
     {                                        
      using (SqlConnection conn = new SqlConnection (ConnectionString))                        
      {                                        
       using (SqlCommand cmd = new SqlCommand (sql , conn))                          
       {                                       
        conn.Open ();                                   
        using (SqlDataReader rdr = cmd.ExecuteReader ())                           
        {                                       
         var mylist = new List<T> { };                               
         while (rdr.Read ())                                 
         {                                      
          if (!Convert.IsDBNull (rdr[0]) || (exclude_nulls == false && replace_null_with_default == false))              
          {                                      
           mylist.Add ((T) Convert.ChangeType (rdr[0] , typeof (T)));                       
          }                                      
          else                                     
          {                                      
           if (exclude_nulls == false)                               
           {                                     
            if (replace_null_with_default == true) mylist.Add (default (T)); // returns the default for the type... not null        
           }                                     
          }                                      
         }                                      

         return mylist;                                   

        }                                       
       }                                       
      }                                        
     }                                        

     public List<IDataRecord> ExecReader(string sql)                             
     {                                        
      using (SqlConnection conn = new SqlConnection (ConnectionString))                        
      {                                        
       using (SqlCommand cmd = new SqlCommand (sql , conn))                          
       {                                       
        conn.Open ();                                   
        using (SqlDataReader rdr = cmd.ExecuteReader ())                           
        {                                       
         return rdr.Cast<IDataRecord> ().ToList ();                           

        }                                       
       }                                       
      }                                        
     }                                        

     public int ExecNonQuery(string sql)                                
     {                                        
      int result = 0;                                    
      using (SqlConnection cn = new SqlConnection (ConnectionString))                        
      {                                        
       using (SqlCommand cmd = new SqlCommand (sql , cn))                           
       {                                       
        cmd.CommandType = CommandType.Text; // or CommandType.StoredProcedure                     
        cn.Open ();                                    

        try                                      
        {                                       
         result = (Int32) cmd.ExecuteNonQuery ();    //returns the number of rows affected               
        }                                       
        finally                                     
        {                                       
         cn.Close ();                                   
        }                                       

       }                                       
      }                                        
      return result;                                    
     }                                        

    }                                         
}                                         
関連する問題