SqlParameter уже содержится в другой коллекции SqlParameterCollection - обманывает ли using () {}?

При использовании с использованием блоков () {} (sic), как показано ниже, и при условии, что cmd1 не выходит за рамки первого с использованием () {} , почему второй блок должен генерировать исключение с сообщением

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);
        }
    }
}

ПРИМЕЧАНИЕ: Выполнение cmd1.Parameters.Clear () непосредственно перед последней фигурной скобкой в first using () {} блок избавит вас от исключения (и возможного затруднения).

Если вам нужно воспроизвести, вы можете использовать следующие скрипты для создания объектов:

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
76
задан marc_s 30 January 2019 в 18:39
поделиться