Пишем:
[SqlProcedure]
public static void DispTest()
{
SqlCommand cmd = new SqlCommand("SELECT * FROM HumanResources.Department");
SqlContext.Pipe.ExecuteAndSend(cmd);
cmd.Dispose();
}
Компилируем, деплоим, запускаем, наслаждаемся:
Msg 6522, Level 16, State 1, Procedure DispTest, Line 0 A .NET Framework error occurred during execution of user defined routine or aggregate 'DispTest': System.Security.HostProtectionException: Attempted to perform an operation that was forbidden by the CLR host. The protected resources (only available with full trust) were: All The demanded resources were:SharedStateПосле серии коротких экспериментов выясняется, что виноват во всем невиниейший Dispose() объекта SqlCommand, забегая вперед скажу, что с SqlConnection та же история...
Но далее, самое забавное, переписываем эти три строчки, как учили:
[SqlProcedure]
public static void DispTest()
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM HumanResources.Department"))
{
SqlContext.Pipe.ExecuteAndSend(cmd);
}
//cmd.Dispose();
}
Компилируем, деплоим, запускаем... и это работает... Почему происходит именно так?
Классы SqlCommand и SqlConnection не имеют публичных реализаций метода Dispose(), они имеют модификатор internal. Но эти классы являются наследниками ComponentModel.Component, где и реализован публичный метод Dispose() и именно он вызывается напрямую, если написать <SqlCommand>.Dispose() или <SqlConnection>.Dispose(), но так как родительский класс находится в другой сборке, то явный вызов метода этого класса приводит к вышеописанному исключению.
Однако, как хорошо заметно на втором примере, путем оборачивания в using явного вызова Dispose() можно избежать..