尽管DataAccessKind.Read存在,但SqlFunction无法打开上下文连接

Ant*_*nes 10 .net c# sql-server sqlclr user-defined-functions

我有一个非常简单的测试表值函数上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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,连接上的"打开"当前已注释掉.部署后,我可以在SQL中执行如下操作: -

SELECT * FROM [dbo].[TestConn](1)
Run Code Online (Sandbox Code Playgroud)

一切正常.

现在我取消注释con.open(),它失败了: -

在此上下文中不允许数据访问.上下文是未使用DataAccessKind.Read或SystemDataAccessKind.Read标记的函数或方法,是从表值函数的FillRow方法获取数据的回调,或者是UDT验证方法.

我没有看到问题是什么,TestConn函数已经有了DataAccessKind.Read.

有人知道任何其他原因导致此错误?

Nes*_*tor 14

问题如下:

  1. SQLCLR不允许在TestFillRow中进行任何数据访问

  2. 即使它"看起来"像你的TestFillRow不能访问数据,编译器使用"yield"语句转换代码的方式实际上是将它的执行推迟到第一次.MoveNext()调用迭代器.因此以下声明:

    using (SqlConnection con = new SqlConnection("context connection=true"))        
    
    Run Code Online (Sandbox Code Playgroud)

    在里面执行TestFillRow......这是非法的.

不要使用收益率 ; 而是将整个结果加载到a List<>并返回UD函数末尾的列表.

  • 连接*在`TestFillRow`中打开*不是问题.即使您提供了自己的"渴望"实现的枚举器,它打开连接并获取main方法中的第一行,该枚举器也无法从`TestFillRow`工作,因为连接将被强制关闭. (2认同)