私はこれを私のコードでかなりたくさん書いているようです:
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
result = new User((int)reader["UserId"], reader["UserName"].ToString());
}
if (reader.Read())
{
throw new DataException("multiple rows returned from query");
}
}
私が知らない、これを行うための組み込みの方法はありますか?
わかりませんが、このコードは拡張メソッドに委任できます。
public static R Single<R>(this DataReader reader, Func<DataReader,R> selector) {
R result = default(R);
if (reader.Read())
result = selector(reader);
if (reader.Read())
throw new DataException("multiple rows returned from query");
return result;
}
そのように使用される:
using (var reader = cmd.ExecuteReader())
{
User u = reader.Single(r => new User((int)r["UserId"], r["UserName"].ToString()))
}
コードの重複からあなたを救います。
これは、目標が何であるかによって、役立つ場合と役に立たない場合があります。適切な例外をスローするために複数の行が返されたことを検出する必要がある場合、これは役に立ちません。
結果が1つだけ返されるようにしたい場合は、このメソッドを使用するとパフォーマンスが向上する可能性があります。私の理解では、データプロバイダーはこれを使用して、単一行の結果を見越してクエリを最適化できます。
いずれの場合も、SqlCommand.ExecuteReaderを使用してデータリーダーを作成しますが、CommandBehavior列挙体(具体的にはCommandBehavior.SingleRow)から引数を渡します。 ExecuteReaderは、これを受け入れるためにオーバーロードされています。
SqlCommand.ExecuteReaderオーバーロード
したがって、コードは次のようになります。
using (var reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (reader.Read())
{
result = new User((int)reader["UserId"], reader["UserName"].ToString());
}
}
SQLを使用してデータをフェッチしている場合、データリーダーを使用する必要があるすべてのインスタンスでその種のコーディングを削除できるようにすることで役立つ場合があります。
SELECT TOP ([Number of rows you want to be selected])
FROM [Table Name]
WHERE [Condition]
例:
SELECT TOP (1)
FROM tblUsers
WHERE Username = 'Allan Chua'
別のヒントでは、ストアドプロシージャを使用します。これらを使用すると、SQLクエリの繰り返しと不要なコーディングを最小限に抑えることができます。