新しいアイデアを見つけると、いつもそれに固執し、弱点が見えません。大規模なプロジェクトで新しいアイデアを使用し始めたときに悪いことが起こり、後でそのアイデアが非常に悪く、どのプロジェクトでも使用すべきではないことに気づきました。
そういうわけで、新しいアイデアを持っていて、それを新しい大規模なプロジェクトで使用する準備ができているので、それについてあなたの意見、特に否定的な意見が必要です。
長い間、データベースに直接アクセスする必要があるプロジェクトで、次のブロックを何度も入力したり、コピーして貼り付けたりすることに飽き飽きしていました。
string connectionString = Settings.RetrieveConnectionString(Database.MainSqlDatabase);
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (SqlCommand getProductQuantities = new SqlCommand("select ProductId, AvailableQuantity from Shop.Product where ShopId = @shopId", sqlConnection))
{
getProductQuantities.Parameters.AddWithValue("@shopId", this.Shop.Id);
using (SqlDataReader dataReader = getProductQuantities.ExecuteReader())
{
while (dataReader.Read())
{
yield return new Tuple<int, int>((int)dataReader["ProductId"], Convert.ToInt32(dataReader["AvailableQuantity"]));
}
}
}
}
だから私は、上記と同じことをするためにそのようなものを書くことを可能にする小さなクラスを作りました:
IEnumerable<Tuple<int, int>> quantities = DataAccess<Tuple<int, int>>.ReadManyRows(
"select ProductId, AvailableQuantity from Shop.Product where ShopId = @shopId",
new Dictionary<string, object> { { "@shopId", this.Shop.Id } },
new DataAccess<string>.Yield(
dataReader =>
{
return new Tuple<int, int>(
(int)dataReader["ProductId"],
Convert.ToInt32(dataReader["AvailableQuantity"]);
}));
2 番目のアプローチは次のとおりです。
短く書くと、
読みやすく(少なくとも私にとっては、実際にははるかに読みにくいと言う人もいるかもしれません)、
エラーが発生しにくい (たとえば、最初のケースでは、接続を使用する前に接続を開くのを忘れたり、
while
ブロックを忘れたりするなど)、インテリセンスの助けを借りてより速く、
特に単純なリクエストの場合、はるかに凝縮されています。
例:
IEnumerable<string> productNames = DataAccess<string>.ReadManyRows(
"select distinct ProductName from Shop.Product",
new DataAccess<string>.Yield(dataReader => { return (string)dataReader["ProductName"]; }));
小さなプロジェクトで simple とジェネリックを使用してそのようなことを実装した後ExecuteNonQuery
、コードExecuteScalar
がはるかに短くなり、保守が容易になったことを嬉しく思います。ReadManyRows
DataAccess<T>.ReadManyRows
私は2つの欠点しか見つけませんでした:
要件の変更によっては、大幅なコード変更が必要になります。たとえば、トランザクションを追加する必要がある場合、通常の
SqlCommand
アプローチで非常に簡単に行うことができます。代わりに私のアプローチを使用すると、プロジェクト全体をSqlCommand
s とトランザクションを使用するように書き直す必要があります。コマンド レベルでのわずかな変更により、私のアプローチから標準
SqlCommand
の s に移行する必要があります。たとえば、1 行のみを照会する場合、このケースを含めるようにクラスを拡張するか、代わりにコードで withをDataAccess
直接使用する必要があります。SqlCommand
ExecuteReader(CommandBehavior.SingleRow)
少しパフォーマンスが低下する可能性があります (正確な指標はまだありません)。
このアプローチの他の弱点は何DataAccess<T>.ReadManyRows
ですか?