How to best clean up a SQLDataReader when using linq

让人想犯罪 __ 提交于 2019-12-08 07:29:12

问题


I have a method that returns a data reader. Normally I would wrap a using around the data reader so that it gets disposed nicely after I iterate through it. THe problem is that I've chosen to consume the data reader using Linq, which means that the defered execution causes the reader to get disposed early. Is there a proper pattern to consume and dispose of the data reader using Linq without having to built a complete collection of it's contents?

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

回答1:


You need to actually read from the reader inside the using block:

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

This will evaluate to code with the same or consistent return type with what you had before, but doesn't close the reader until after you're done reading from it.




回答2:


Shooting from the hip here. This should help you decouple the reader logic as well.

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"] };
}


来源:https://stackoverflow.com/questions/16179996/how-to-best-clean-up-a-sqldatareader-when-using-linq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!