使用linq时如何最好地清理SQLDataReader

时间:2013-04-23 22:06:25

标签: c# linq sqldatareader

我有一个返回数据读取器的方法。通常情况下,我会在数据读取器周围进行一次使用,以便在迭代它之后很好地处理它。问题是我选择使用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)
    });
}

2 个答案:

答案 0 :(得分:8)

您需要实际读取使用块内的阅读器:

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)
        };
    }
}

这将评估使用与之前相同或一致的返回类型的代码,但是在之后完成阅读之前不会关闭阅读器。

答案 1 :(得分: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"] };
}