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

我的数据层中有以下类型的代码,可以从控制台应用程序,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(sql, new {datasetID } ).First(); } } 

我现在想从SQLCLR存储过程(在存在这些表的数据库中)调用相同的代码,您通常使用上下文连接 :

 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(sql, new {datasetID } ).First(); } 

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

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

以面值来表达问题(及其评论),你为什么需要:

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

? 对于OpenDispose您应该将Context Connection视为与任何其他连接相同。 听起来你正在考虑使用SqlConnection ,当使用"Context Connection = true;"的连接字符串时 ,只需要打开一次,然后直到完全完成才能Open ,否则你会Open /弃置几次。 我认为没有理由在这两种情况下有不同的行为。


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

  1. 不对应用程序代码进行任何更改,但依赖于其他配置文件:

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

           

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

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

    通过使用SqlContext类的IsAvailable属性,您可以轻松地自动检测您当前是否正在SQL Server的CLR主机中运行。 只需更新您的原始代码,如下所示:

     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; } 

    顺便提一下,这种用法在IsAvailable属性的链接MSDN页面的“备注”部分中IsAvailable