1

我有一个返回数据读取器的方法。通常我会在数据阅读器周围包裹一个 using ,以便在我遍历它之后很好地处理它。问题是我选择使用 Linq 使用数据读取器,这意味着延迟执行会导致读取器提前处理。是否有适当的模式来使用 Linq 使用和处理数据读取器,而无需构建其内容的完整集合?

using (System.Data.SqlClient.SqlDataReader reader = CallStoredProcedure())
{
    return reader.Cast<System.Data.Common.DbDataRecord>().Select(rec => new ObjectModel.CollectorSummaryItem()
    {
        CollectorID = (int)rec[0],
        Name = rec.IsDBNull(1) ? null : rec.GetString(1),
        Information = rec.IsDBNull(2) ? null : rec.GetString(2)
    });
}
4

2 回答 2

8

您需要从 using 块内的阅读器中实际读取:

using (System.Data.SqlClient.SqlDataReader reader = CallStoredProcedure())
{
    while (reader.Read())
    {
        yield return new ObjectModel.CollectorSummaryItem()
        {
            CollectorID = (int)reader[0],
            Name = reader.IsDBNull(1) ? null : reader.GetString(1),
            Information = reader.IsDBNull(2) ? null : reader.GetString(2)
        };
    }
}

这将评估为具有与您之前所拥有的相同或一致的返回类型的代码,但在您完成读取之前不会关闭阅读器。

于 2013-04-23T22:11:33.567 回答
0

在这里从臀部射击。这也应该有助于您解耦阅读器逻辑。

public IEnumerable<MyObject> ExecuteNonQuery(...)
{
  ...
  using(var reader = comm.ExecuteReader())
  {
    var results = new List<MyObject>();
    return reader
            .Cast<System.Data.Common.DbDataRecord>()
            .Select(rec => GetFromReader(rec))
            .ToList();
  }
}

public MyObject GetFromReader(IDataRecord rdr)
{
   return new MyObject { Prop1 = rdr["prop1"], Prop2 = rdr["prop2"] };
}
于 2013-04-24T03:30:23.917 回答