ExecuteDataset()
必要なことはすでに実行されます。データセットは、ある意味では、DataTable の単なるコレクションです。
通常は DataReader を使用しますが、データ ロジック レイヤーを作成しているため、DataTable は接続を存続させる必要があります (DataReader は接続を存続させることはできません)。
この場合、ExecuteDatatable() メソッドを作成する代わりにExecuteEnumerable()
、Iterator ブロックで DataReader を使用するメソッドを作成することをお勧めします。コードは次のようになります。
Public Shared Iterator Function ExecuteEnumerable(Of T)( ... ) As IEnumerable(Of T)
Using cn As New SqlConnection( ... ), _
cmd As New SqlCommand( ... )
'As needed
'cmd.Parameters.Add( ... ).Value = ...
Using rdr As SqlDataReader = cmd.ExecuteReader()
While rdr.Read()
Yield transform(rdr)
End While
End Using
End Using
End Function
いくつかのことをスキップしたことに気付くでしょう。私は既存の SqlHelper.vb ファイルに慣れていないので、既存のスタイルに合わせたいので、それに合わせてコードに余裕を持たせました。ただし、強調したい重要な部分が 2 つあります。
- cmd.Parameters.Add() 呼び出しに注意してください。ユーティリティ SQL ヘルプ クラスの一般的な失敗の 1 つは、クエリ パラメータを適切に提供できないことです。多くの場合、その結果は恐ろしく安全でないコードになります。既存のメソッドにパラメーター データを渡す方法が現在ない場合は、作成する必要があります。それが優先度1です。
- そこでの
transform(rdr)
呼び出しではFunc(IDataRecord, T)
、関数の引数として指定する必要があるデリゲートが使用されます。ExecuteEnumerable() 反復子の概念が機能するには、各反復で SqlDataReader オブジェクトの現在の値のコピーを取得する必要があります。ここで、DataTable で使用する DataRow タイプで行われるように、ある種の一般的なデータ転送オブジェクトを設定できます。ただし、ある型のジェネリック データ トランスポート オブジェクトへのコピーを作成するために CPU とメモリの時間を費やすよりも、デリゲートを使用してコードを厳密に型指定されたビジネス オブジェクトに直接コピーすることを好みます。欠点は、メソッドを呼び出すたびに、特定のオブジェクトに対してそれを行う方法についての指示を送信する必要があることです。ただし、ほとんどの場合、これはビジネス オブジェクトの共有ファクトリ メソッドを使用するだけで簡単に実行できます。