从Console App或SQLCLR对象调用函数时处理连接的最佳方法(“Context Connection = true”)

时间:2015-07-07 05:19:19

标签: c# sql-server sqlclr

我的数据层中有以下类型的代码,可以从控制台应用程序,Windows应用程序等调用,并从相应的调用者的App.Config文件中读取正确的连接字符串:

public static udsDataset GetDataset(int datasetID)         
{
   string connectionString = 
             ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
   string sql = @"select * from Dataset WHERE DatasetID=@datasetID";

   using (SqlConnection conn = new SqlConnection(connectionString))
   {
      // Dapper query:            
      return conn.Query<udsDataset>(sql, new {datasetID } ).First();
   }    
}

我现在想从SQLCLR存储过程(在存在这些表的数据库中)调用相同的代码,通常使用context connection

using(SqlConnection connection = new SqlConnection("context connection=true")) 
{
    connection.Open();
    // etc etc etc
}

最让人想到的方法是重载函数:

public static udsDataset GetDataset(int datasetID)
{
   string connectionString = 
       ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

   using (SqlConnection conn = new SqlConnection(connectionString))
   {
      return GetDataset(datasetID, conn);
   }
}

public static udsDataset GetDataset(int datasetID, SqlConnection conn)         
{
    // caller is responsible for closing and disposing connection
    string sql = @"select * from Dataset WHERE DatasetID=@datasetID";

    return conn.Query<udsDataset>(sql, new {datasetID } ).First();
}

因此,使用App.Config的应用程序可以调用无连接版本,SQLCLR可以调用需要SqlConnection的版本。

这似乎“好看”,但是必须为每个相似的函数编写完全相同的重载样式,这会让人觉得不对。

1 个答案:

答案 0 :(得分:3)

在面值上提出问题(及其评论),为什么需要:

  

从SQLCLR过程调用时传入现有连接的选项

?您应该将Context Connection视为与OpenDispose相关的任何其他连接一样。听起来你认为SqlConnection在使用"Context Connection = true;"的连接字符串时,只需要打开一次,然后在完成之前不会被释放,而你会Open / {其中{1}}多次。我认为没有理由在这两种情况下有不同的行为。

除此之外,如何最好地处理检测环境变化(在Console App和SQLCLR对象之间)?你有两个选择,两者都可能比你期望的更容易:

  1. 对应用代码进行更改,但依赖其他配置文件:

    您可以在Dispose文件夹中创建名为sqlservr.exe.Config的文件(例如C:\Program Files\Microsoft SQL Server\MSSQL{SqlVersion}.{SqlServerInstanceName}\MSSQL\Binn,其中C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn中的11适用于SQL Server 2012。该文件的格式应该如预期的那样:

    MSSQL11

    这个可能被认为是“更干净”的代码,但确实引入了一个外部依赖关系,你的DBA可能没问题,可能不喜欢但容忍,或者可能会要求你的经理给你写信; - )。

  2. 对应用代码进行非常次要更改,但不要依赖其他配置文件:

    您可以使用<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="CoolioAppDB" connectionString="Context Connection = true;" /> </connectionStrings> </configuration> 类的IsAvailable属性轻松自动检测您当前是否在SQL Server的CLR主机中运行。只需更新原始代码,如下所示:

    SqlContext

    顺便提一下,这种用法在string connectionString = "Context Connection = true;"; // default = SQLCLR connection if (!SqlContext.IsAvailable) // if not running within SQL Server, get from config file { connectionString = ConfigurationManager.ConnectionStrings["CoolioAppDB"].ConnectionString; } 属性的链接MSDN页面的“备注”部分中注明。