2017-04-05 119 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

相关问题