将 SqlDataReader 移至外部函数对性能有何影响?

Any performance implications of moving SqlDataReader to external function?

给定以下 SQLCLR 函数:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void ExecSQL(string sql, string connectionString)  
{
    WindowsIdentity clientId = null;
    WindowsImpersonationContext impersonatedUser = null;
    clientId = SqlContext.WindowsIdentity;
    try
    {
        try
        {
            impersonatedUser = clientId.Impersonate();
            if (impersonatedUser != null)
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {

                    //** HERE I WILL HAVE MULTIPLE VARIATIONS OF FETCHING THE SQLDATAREADER
                    connection.Open();
                    SqlCommand command = new SqlCommand(sql, connection);
                    SqlDataReader r = command.ExecuteReader();
                    impersonatedUser.Undo();
                    SqlContext.Pipe.Send(r);
                }
            }
            else
            { throw new Exception("Impersonation failed."); }
        }
        finally
        {
            if (impersonatedUser != null) { impersonatedUser.Undo(); }
        }
    }
    catch
    {
        throw;
    }
}

移动此部分是否有任何性能或其他后果:

                connection.Open();
                SqlCommand command = new SqlCommand(sql, connection);
                SqlDataReader r = command.ExecuteReader();

进入单独的 GetDataReader() 方法?

我问是因为我知道我要为许多不同的场景(Sql 文本、存储过程、Table 值函数、标量函数等)加载数据读取器,所以我我想将每个不同的实现封装到它们自己的函数中,而不是在这个函数中间有一个大的 switch 语句。

Are there any performance or other ramifications

不是我能想到的或运行成的。当然,当涉及到这种性质的与性能相关的问题时,我总是建议测试一下,看看哪个更好,因为任何人回答问题都可能是错误的,并且肯定存在“接受”答案不正确的情况。然而,您的系统上的软件 运行ning 是最终的答案:-)。


除此之外,还有一些关于问题中显示的代码片段的注释。

  1. 可以impersonatedUser.Undo();移动到connection.Open();之后。只需要建立连接。但是,话又说回来,将 Impersonation 处理保留在 main 方法中而不是仅将 Undo() 移动到新方法可能会更干净。

    或者,您也可以将 connection.Open(); 保留在此处的主要方法中。在任何一种情况下,您都必须传递 connection 对象。

  2. 您可以将 impersonatedUser = clientId.Impersonate(); 包装在 if 条件中,测试 connectionString 以查看它是否是 "Context Connection = true;"。这将允许您使用上下文连接,否则它将无法工作,因为它不能与模拟一起使用。我想您可以重新处理当前的 if (impersonatedUser != null),因为该测试将不再有效(新测试只关心 impersonatedUser 是否为 null,如果上下文连接不是使用。

  3. WindowsImpersonationContext是一次性的,所以最好把你的finally块移到外面的try,然后在后面加上impersonatedUser.Dispose(); Undo().