通过调用栈实现一个sql上下文连接

本文关键字:一个 sql 上下文 连接 调用 实现 | 更新日期: 2023-09-27 18:03:45

我必须在SQL Server 2008 R2上部署两个用户定义的标量值函数,如下所示。它们都可以单独调用。第一个也可以从第二个调用。

[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static bool Function1(string arg1)
{
    using (SqlConnection sqlCnn = new SqlConnection("context connection=true"))
    {
        //... Some code here.
    }
    return true;
}
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static bool Function2(string arg1)
{
    using (SqlConnection sqlCnn = new SqlConnection("context connection=true"))
    {
        bool ret1 = Function1("arg1");
        //... Some code here.
    }
    return true;
}

部署成功。但是,如果调用Function2,则会引发以下错误:

"系统。InvalidOperationException:上下文连接已经存在在使用"

问题是:

  1. 调用一个从数据库获取数据的函数从另一个从同一数据库获取数据的函数(常规连接;

  2. 值得信赖的属性是关闭的,所以我不能打开常规连接。考虑到这一事实,最好的解决方案是什么?

通过调用栈实现一个sql上下文连接

代码中有打字错误吗?看起来你有无限递归与Function2调用自己。对于我的答案,我假设它应该调用Function1。

我对Microsoft.SqlServer.Server.SqlFunction不太熟悉,但是如果您可以重载函数,那么下面的内容将对您有所帮助。

[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static bool Function1(string arg1)
{
    using (SqlConnection sqlCnn = new SqlConnection("context connection=true"))
    {
        return Function1(arg1, sqlCnn);
    }
    return true;
}
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static bool Function1(string arg1, SqlConnection sqlCnn)
{
    //... Some code here using sqlCnn which we won't close or dispose.
    // as it's up to the caller to do that
    return true;
}
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static bool Function2(string arg1)
{
    using (SqlConnection sqlCnn = new SqlConnection("context connection=true"))
    {
        bool ret1 = Function1(arg1, sqlCnn);
        //... Some code here.
    }
    return true;
}

,所以任何调用Function1可以使用Function1(string),它将创建自己的连接,但Function2调用Function1(string, SqlConnection),然后使用相同的连接。

SqlFunction方法,如FunctionFunction2实际上是你的代码到SQL Server的接口,不应该依赖于彼此。如果出现这种情况,说明你的代码开始变得过于复杂,不适合简单的静态方法。

一个更好的解决方案是将连接管理留给SqlFunction方法,并将实际实现放在其他方法中,例如:

[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static bool Function1(string arg1)
{
    using (SqlConnection sqlCnn = new SqlConnection("context connection=true"))
    {
        InnerFunction1(sqlCnn,arg1);
    }
    return true;
}
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static bool Function2(string arg1)
{
    using (SqlConnection sqlCnn = new SqlConnection("context connection=true"))
    {
        InnerFunction2(sqlCnn,"arg1");
    }
    return true;
}
private static bool InnerFunction1(SqlConnection sqlCnn,string arg1)
{
        //... Some code here.   
}
private static bool InnerFunction2(SqlConnection sqlCnn,string arg1)
{
        bool ret1 = InnerFunction1(sqlCnn,"arg1");
        //... Some code here.           
}

如果您有许多这样的函数,您可以将其实现适当地提取到其他类中,并保留静态类仅用于公开SqlFunction成员。

将函数调用移出using块