using() {}
以下に示すように(sic)ブロックを使用し、それcmd1
が最初のusing() {}
ブロックの範囲を超えて存在しないと仮定しているときに、2番目のブロックがメッセージとともに例外をスローする必要があるのはなぜですか
SqlParameterは、別のSqlParameterCollectionにすでに含まれています
ブロックの最後で破棄されたときに、SqlParameterCollection
アタッチされcmd1
ているリソースやハンドル(パラメーター()を含む)が解放されないことを意味しますか?
using (var conn = new SqlConnection("Data Source=.;Initial Catalog=Test;Integrated Security=True"))
{
var parameters = new SqlParameter[] { new SqlParameter("@ProductId", SqlDbType.Int ) };
using(var cmd1 = new SqlCommand("SELECT ProductName FROM Products WHERE ProductId = @ProductId"))
{
foreach (var parameter in parameters)
{
cmd1.Parameters.Add(parameter);
}
// cmd1.Parameters.Clear(); // uncomment to save your skin!
}
using (var cmd2 = new SqlCommand("SELECT Review FROM ProductReviews WHERE ProductId = @ProductId"))
{
foreach (var parameter in parameters)
{
cmd2.Parameters.Add(parameter);
}
}
}
注:最初のusing(){}ブロックの最後の括弧の直前にcmd1.Parameters.Clear()を実行すると、例外(および起こりうる恥ずかしさ)からあなたを救うことができます。
再現する必要がある場合は、次のスクリプトを使用してオブジェクトを作成できます。
CREATE TABLE Products
(
ProductId int IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
ProductName nvarchar(32) NOT NULL
)
GO
CREATE TABLE ProductReviews
(
ReviewId int IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
ProductId int NOT NULL,
Review nvarchar(128) NOT NULL
)
GO