2017-04-05 14 views
0

の単一の列という値を返すクエリに対して、T型のコレクションを取得するメソッドを記述しようとしています。SqlDataReaderからIEnumerableへ<T>

public static IEnumerable<T> ExecuteReader<T>(string query) 
{ 
    using (SqlConnection cn = new SqlConnection(conn.ConnectionString)) 
    { 
     cn.Open(); 
     using (SqlCommand cmd = new SqlCommand(query, cn)) 
     { 
      using (SqlDataReader reader = cmd.ExecuteReader()) 
      { 
       while (reader.Read()) 
       { 
        yield return (T)reader[0]; 
       } 
      } 
     } 
    } 

使用例:

foreach (var dbname in ExecuteReader<string>("SELECT Name FROM sys.databases")) 
{ 
    //iterate db names 
} 

問題は今、私は、のtry/catchでコードにエラー処理を追加したいのですが、私がこれまで試したどのような

次のようなもの:

try 
{ 
    //my code 
} 
catch 
{ 
    //Error handling code 
    return Enumerable.Empty<T>(); 
} 

利回りはtry/catchと互換性がありません。

IDataReaderクラスの拡張機能を作成するなど、Web上でいくつかの選択肢が見られましたが、旧式になる可能性があるので、これを実現するための提案や改善方法が公開されています。

EDIT:

私は答えのように感じるが、多分私は自分自身を明確にするdidntは、質問自体から逸脱しています。 try-catchまたはの出力は、私にはとは関係ありません。これはコードを書いた後に見つけられた小さな障害です。

私が知りたいのは、これが、汎用タイプの単一の列が取り出されたデータウェアハウスからリストを取り込む正しい方法であるかどうかです。

+0

したがって、yieldを使用せず、すべてをリストに入れてからlistを返します。 – Niewidzialny

+0

'try {} catch {return Enumerable.Empty ()}'はエラー処理ではありません。 – Evk

+0

@Evkこれは単なる例であり、いくつかのログにエラーメッセージを登録したいと考えています – Innat3

答えて

2

あなたは、このメソッドをプライベートにとプライベートメソッドを呼び出す同じシグネチャを持つpublicメソッドを作成することができます。

public static IEnumerable<T> ExecuteReader<T>(string query) 
{ 
    try{ 
     return executeReader<T>(query); 
    } 
    catch(Exception ex){ 
     // your handling code here 
    } 
} 

private static IEnumerable<T> executeReader<T>(string query) 
{ 
    // same code as you have above in your example 

    using (SqlConnection cn = new SqlConnection(conn.ConnectionString)) 
    { 
     cn.Open(); 
     using (SqlCommand cmd = new SqlCommand(query, cn)) 
     { 
      using (SqlDataReader reader = cmd.ExecuteReader()) 
      { 
       while (reader.Read()) 
       { 
        yield return (T)reader[0]; 
       } 
      } 
     } 
    } 
} 

また、キャッチしても発信者が例外を心配することはありません。 try/catchブロックが多いような方法でコードを書くこともできますが、yieldは@Evkが示唆するように決して1つには見つかりません。

+0

はい、これは有効な回避策です。これ以上有効な代替案がない場合は、後で有効な回答と見なします。 – Innat3

+0

私はちょうど私の質問のポイントは、利回りをtry-catchで使うことができない理由を理解していなかったことを付け加えたいので、私の質問に重複してフラグを立てるために少し怒っている。 – Innat3

+0

@ Innat3 - あなたの編集。あなたの質問の最後の非コード1/2が 'yield'と' try/catch'の問題に集中していたので、それはあまり明確ではなかったと思います。 – Igor

関連する問題