我有一个非常简单的测试表值函数上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
.
有人知道任何其他原因导致此错误?
问题如下:
SQLCLR不允许在TestFillRow中进行任何数据访问
即使它"看起来"像你的TestFillRow不能访问数据,编译器使用"yield"语句转换代码的方式实际上是将它的执行推迟到第一次.MoveNext()调用迭代器.因此以下声明:
using (SqlConnection con = new SqlConnection("context connection=true"))
在里面执行TestFillRow
......这是非法的.
不要使用收益率 ; 而是将整个结果加载到a List<>
并返回UD函数末尾的列表.