Wenn Sie die using() {}
(sic) -Blöcke wie unten gezeigt verwenden und davon ausgehen, dass cmd1
sie nicht über den Umfang des ersten using() {}
Blocks hinausgehen , warum sollte der zweite Block eine Ausnahme mit der Nachricht auslösen?
Der SqlParameter ist bereits in einer anderen SqlParameterCollection enthalten
Bedeutet dies, dass Ressourcen und / oder Handles - einschließlich der Parameter ( SqlParameterCollection
) -, an die sie angehängt cmd1
sind, nicht freigegeben werden, wenn sie am Ende des Blocks zerstört werden?
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);
}
}
}
HINWEIS: Wenn Sie cmd1.Parameters.Clear () kurz vor der letzten Klammer des ersten using () {} -Blocks ausführen , werden Sie vor der Ausnahme (und möglichen Verlegenheit) bewahrt .
Wenn Sie reproduzieren müssen, können Sie die Objekte mit den folgenden Skripten erstellen:
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