使用("Context connection =true")从控制台应用程序或SQLCLR对象调用函
本文关键字:quot 应用程序 SQLCLR 对象 控制台 调用 true Context connection 使用 | 更新日期: 2023-09-27 18:01:30
我的数据层中有以下类型的代码,可以从控制台应用程序,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存储过程(在存在这些表的数据库中)调用相同的代码,您通常会在其中使用上下文连接:
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的版本。
这"看起来不错",但是必须为每个类似的函数编写完全相同样式的重载,这让人感觉不对劲。
从表面上看,你为什么需要:
从SQLCLR过程调用时传入现有连接的选项
?您应该将Context Connection
视为与Open
和Dispose
有关的任何其他连接一样。听起来像你认为SqlConnection
,当使用"Context Connection = true;"
的连接字符串时,只需要打开一次,然后不处理,直到完全完成,而你会Open
/Dispose
几次否则。我看不出有什么理由在这两种情况下有不同的行为。
撇开所有这些,如何最好地处理检测环境中的变化(在控制台应用程序和SQLCLR对象之间)?你有两个选择,可能都比你想象的要简单:
-
让不改变应用程序代码,但依赖于一个额外的配置文件:
您可以在
C:'Program Files'Microsoft SQL Server'MSSQL{SqlVersion}.{SqlServerInstanceName}'MSSQL'Binn
文件夹中创建一个名为sqlservr.exe.Config
的文件(例如C:'Program Files'Microsoft SQL Server'MSSQL11.MSSQLSERVER'MSSQL'Binn
,其中MSSQL11
中的11
用于SQL Server 2012)。这个文件的格式,可能应该是预期的,如下所示:<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="CoolioAppDB" connectionString="Context Connection = true;" /> </connectionStrings> </configuration>
这个可能被认为是"更干净"的代码,但确实引入了一个外部依赖,DBA可能会接受,可能不喜欢但容忍,或者可能要求您的经理将您写下来;
-
对应用代码做一个非常小的更改,但不要依赖于额外的配置文件:
你可以很容易地自动检测是否你当前运行在SQL server的CLR主机通过使用
SqlContext
类的IsAvailable属性。只需更新您的原始代码如下: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页面的"备注"部分中有说明。