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 に答える