Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

While using the using() {} (sic) blocks as shown below, and assuming that cmd1 does not live beyond the scope of the first using() {} block, why should the second block throw an exception with the message

The SqlParameter is already contained by another SqlParameterCollection

Does it mean that resources and/or handles - including the parameters (SqlParameterCollection) - attached to cmd1 are not released when its destroyed at the end of the block?

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: Doing cmd1.Parameters.Clear() just before the last brace of the first using() {} block will save you from the exception (and possible embarrassment).

If you need to reproduce you can use the following scripts to create the objects:

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
584 views
Welcome To Ask or Share your Answers For Others

1 Answer

I suspect that SqlParameter "knows" which command it's part of, and that that information isn't cleared when the command is disposed, but is cleared when you call command.Parameters.Clear().

Personally I think I'd avoid reusing the objects in the first place, but it's up to you :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...