我的数据层中有以下类型的代码,可以从控制台应用程序、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 的版本。
这“看起来没问题”,但是必须为每个相似的函数编写完全相同的重载风格,这让人感觉不对。
最佳答案
从表面上看这个问题(及其评论),你为什么需要:
the option of passing in an existing connection when calling from a SQLCLR procedure
?在Open
和Dispose
方面,您应该将Context Connection
与任何其他连接一样对待。听起来您认为 SqlConnection
在使用 "Context Connection = true;"
连接字符串时只需要打开一次,然后直到完全释放为止完成,否则您将Open
/Dispose
多次。我认为没有任何理由在这两种情况下有不同的行为。
除此之外,如何最好地处理检测环境变化(控制台应用程序和 SQLCLR 对象之间)?您有两种选择,两种选择都可能比您预期的要容易:
对应用代码进行不更改,但依赖于额外的配置文件:
您可以在
C:\Program Files\Microsoft SQL Server\MSSQL{SqlVersion}.{SqlServerInstanceName}\MSSQL\Binn
中创建名为sqlservr.exe.Config
的文件code> 文件夹(例如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 可能会接受,可能不喜欢但容忍,或者可能会要求您的经理给您写信;- )。
对应用代码进行非常微小更改,但不要依赖其他配置文件:
您可以使用 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; }
顺便说一句,此用法在
IsAvailable
属性的链接 MSDN 页面的“备注”部分中进行了说明。
关于c# - 从控制台应用程序或 SQLCLR 对象使用 ("Context Connection=true"调用函数时处理连接的最佳方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31260279/