我在将数据存储到SqlDataReader中时遇到问题。在遍历sdr变量时,在connection.close()处,sdr变量变为空。为什么?
string strConnection = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;
SqlDataReader sdr = null;
using (SqlConnection connection = new SqlConnection(strConnection))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand("GetProducts", connection))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
sdr = cmd.ExecuteReader();
}
connection.Close();
}
return (sdr);发布于 2011-02-16 06:17:15
在调用Read时,您需要在循环中迭代读取器:
while(sdr.Read())
{
var someValue = sdr["SomeValue"]; //Where SomeValue is the column name you're expecting from the DB
}ExecuteReader所做的就是向您返回一个DataReader对象,但是您需要遍历返回的每一行并从中提取值。如果你想一次完成所有的任务,你可以使用SqlDataAdapter:
var adapter = new SqlDataAdapter(command);
var table = new DataTable();
adapter.Fill(table);发布于 2011-02-16 06:31:26
在DataReader上迭代时,您需要一个开放的活动连接。如果您在返回数据读取器之前将其关闭,它将无法工作。我通常要做的就是将DataReader转换为IEnumerable,如下所示:
public IEnumerable<IDataRecord> GetProductsFromDB()
{
string strConnection = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;
using (SqlConnection connection = new SqlConnection(strConnection))
using (SqlCommand cmd = new SqlCommand("GetProducts", connection))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
connection.Open();
using (var sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
yield return sdr;
}
}
}
}请注意,我还稍微更改了一下顺序:尽可能长时间地等待打开连接,并将连接和命令创建放在每个连接旁边,以避免太多嵌套。
这种模式为您编写数据访问代码的方式开辟了一个全新的世界,因为现在您的原始sql查询和存储过程调用突然使用了linq-to-objects操作符。你可以像这样做一些很酷的事情:
foreach (var product in GetProductsFromDB()
.Select(i => CreateProductFromDataRow(i))
.Where(p => p.IsOnSale()) )
{
// do something with products that are on sale
}https://stackoverflow.com/questions/5010139
复制相似问题