2017-04-05 78 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類編寫擴展,但我覺得他們可能已經過時,所以我願意接受建議或更好的方法來實現這一點。

編輯:

我覺得答案是從問題本身偏離,也許我沒有說清楚。 try-catch收益率與我無關,這只是我編寫我的代碼後發現的一個小障礙。

我想知道的是,如果這是從datareader填充列表的正確方式,其中檢索一列泛型類型。

+0

所以不要使用yield,並把所有列表,然後返回列表。 – Niewidzialny

+0

請注意'try {} catch {return Enumerable.Empty ()}'_不是錯誤處理。 – Evk

+0

@Evk僅僅是一個例子,我也想把錯誤信息註冊到一些日誌中 – Innat3

回答

2

您可以將此方法設置爲私有方法,並創建一個具有調用私有方法的相同簽名的公共方法。

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中提供。

+0

是的,這是一個有效的解決方法,如果我沒有收到更多令人滿意的替代方案,我會認爲它是一個有效的答案。 – Innat3

+0

我只想補充一點,我的問題不是要明白爲什麼yield不能用於try-catch,所以我的問題被標記爲 – Innat3

+0

@ Innat3的重複有點讓人氣憤 - 我剛纔看到你的編輯。我認爲這不是很清楚,因爲你問題的最後一個非代碼1/2集中在'yield'和'try/catch'的問題上。 – Igor

相關問題