SqlFunction не удается открыть контекстное соединение, несмотря на наличие DataAccessKind.Read

У меня есть проект SqlServer с очень простым тестом для функции с табличным значением: -

[SqlFunction(TableDefinition = "forename nvarchar(50)", FillRowMethodName = "TestFillRow", DataAccess = DataAccessKind.Read)]
public static IEnumerable TestConn(int ID)
{
    using (SqlConnection con = new SqlConnection("context connection=true"))
    {
        //con.Open();
        yield return "Anthony";
    }
}

public static void TestFillRow(object obj, out string forename)
{
    forename = (string)obj;
}

Обратите внимание, что в настоящее время сообщение «Открыть соединение» закомментировано. После развертывания я могу выполнить в SQL вот так: -

SELECT * FROM [dbo].[TestConn](1)

Все нормально работает.

Теперь я раскомментирую, con.open() и он терпит неудачу: -

В этом контексте доступ к данным запрещен. Либо контекст - это функция или метод, не помеченные как DataAccessKind.Read или SystemDataAccessKind.Read, это обратный вызов для получения данных из метода FillRow функции с табличным значением, либо метод проверки UDT.

Не вижу в чем проблема, у функции TestConn DataAccessKind.Read .

Кто-нибудь знает какие-либо другие причины получения этой ошибки?

Ответов (2)

Решение

Проблема в следующем:

  1. SQLCLR не разрешает доступ к данным внутри TestFillRow

  2. Хотя это «выглядит» так, будто ваш TestFillRow не имеет доступа к данным, компилятор переводит код с помощью операторов yield, фактически откладывая его выполнение до первого вызова .MoveNext () итератору. Поэтому следующее утверждение:

    using (SqlConnection con = new SqlConnection("context connection=true"))        
    

    выполняется внутри TestFillRow... что незаконно.

Не используйте доходность возврата ; вместо этого загрузите весь результат в a List<> и верните список в конце функции UD.

«SQLCLR не разрешает доступ к данным внутри TestFillRow» является ошибкой.

Если вы не используете context connection = true строку подключения, вы можете получить доступ к данным внутри FillRow метода.