2009-10-15 76 views
3

我有这样的代码工作:返回列值化为IEnumerable

public IEnumerable<string> GetEmpNames() 
{ 
    var cmd = SqlCommand("select [EmpName] from [dbo].[Emp]"); 
    using (var rdr = cmd.ExecuteReader()) 
     while (rdr.Read()) 
      yield return (string) rdr["EmpName"]; 
} 

不过,我不知道是否有一个更好的(LINQish)的方式,不必求助于产量回报。 (和的LINQ to SQL是不是一种选择:))

+2

它清晰简洁。完全切换到LINQ to SQL或保持原样。 “收益率回报”没有任何问题。 – 2009-10-15 14:51:20

+0

@JoelFan,*收益率回报*有什么问题?这也是我如何做到的。 – 2009-10-15 14:52:01

+0

@Stan,问题在于你将连接打开的时间超过了它应该是的 – 2009-10-15 15:00:35

回答

5
IEnumerable<string> result = DataContext.ExecuteQuery<string>(sqlstring) 

http://msdn.microsoft.com/en-us/library/bb361109.aspx

+0

我怀疑这会在未执行到枚举的意义上是惰性的,但不是在单一结果中时间感@ Joel的代码。不过,我找不到任何相关文件。 – 2009-10-15 15:42:46

+0

数据库执行是Now(不是懒惰)。我相信行的翻译也是通过DataContext.Translate方法的Now(不是懒惰)。 – 2009-10-15 15:57:05

3

你不应该这样做!您的阅读器需要尽快关闭。您不希望在枚举期间保持打开状态。最好只创建一个明确的列表,然后返回。

var cmd = SqlCommand("select [EmpName] from [dbo].[Emp]"); 
List<string> results = new List<string>(); 
using (var rdr = cmd.ExecuteReader()) { 
    while (rdr.Read()) 
     results.Add((string) rdr["EmpName"]); 
} 
return results; 

您可以通过铸造它放在一个DataReader使用LINQ表达式:

using (var rdr = cmd.ExecuteReader()) { 
    results = (from row in rdr.Cast<DbDataRecord>() 
       select (string)row["EmpName"]).ToList(); 
} 

但是请注意,你需要调用ToList(),或者当您尝试列举你会得到一个错误因为读者已经关闭了。

编辑

似乎是在什么时候它是开放的什么一个DataReader实际上做的评论有些混乱。 From MSDN

当正在使用的SqlDataReader的, 的关联的SqlConnection忙 服务SqlDataReader中,并没有其他 操作可以上 比闭 它以外的的SqlConnection来执行。在调用SqlDataReader的Close 方法之前,情况就是如此。 例如,在调用 关闭之前,您无法检索 输出参数。

因此,您应该尽快关闭以释放连接。

+0

我不会那样做。如果你想把它放在一个列表中,让OP的函数private,并让你的public方法返回GetEmpNames()。ToList()'。 – 2009-10-15 14:56:04

+1

我会说这是来电者的选择。使用原始代码,如果他们有很多工作要做,否则他们可以自己调用ToList()。使用你的代码,即使调用代码实际上只是做一些聚合操作,所有的数据都将被缓冲。你*降低*灵活性。 – 2009-10-15 14:58:22

+0

@Jon你认为可以将连接无限期地打开吗? – 2009-10-15 15:08:39