Lors de l'utilisation du using() {}
(sic) comme indiqué ci-dessous, et en supposant que cmd1
ne vit pas au-delà du champ d'application de la première using() {}
pourquoi le deuxième bloc devrait-il lancer une exception avec le message
Le SqlParameter est déjà contenu dans une autre SqlParameterCollection
Cela signifie-t-il que les ressources et/ou les poignées - y compris les paramètres ( SqlParameterCollection
) - rattaché à cmd1
ne sont pas libérés lorsqu'il est détruit à la fin du bloc ?
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);
}
}
}
NOTE : En faisant cmd1.Parameters.Clear() juste avant la dernière accolade du premier using() {} vous évitera l'exception (et un éventuel embarras).
Si vous avez besoin de reproduire, vous pouvez utiliser les scripts suivants pour créer les objets :
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