gpt4 book ai didi

c# - 使用 ("Context Connection=true"从控制台应用程序或 SQLCLR 对象调用函数时处理连接的最佳方式)

转载 作者:行者123 更新时间:2023-11-30 21:56:45 29 4
gpt4 key购买 nike

我的数据层中有以下类型的代码,可以从控制台应用程序、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

?您应该将 Context Connection 视为与 OpenDispose 相关的任何其他连接。听起来你在想 SqlConnection,当使用 "Context Connection = true;" 的连接字符串时,只需要打开一次,然后直到完全打开才被释放完成,否则你会多次Open/Dispose。我看不出有任何理由在这两种情况下有不同的行为。


除此之外,如何最好地处理检测环境变化(在控制台应用程序和 SQLCLR 对象之间)?您有两个选择,两者都可能比您预期的更容易:

  1. 更改应用代码,但依赖于额外的配置文件:

    您可以在 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 可能会接受,可能不喜欢但可以容忍,或者可能会要求您的经理为您写信;- ).

  2. 对应用代码进行非常微小的更改,但不要依赖额外的配置文件:

    您可以使用 IsAvailable 轻松地自动检测您当前是否在 SQL Servers 的 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# - 使用 ("Context Connection=true"从控制台应用程序或 SQLCLR 对象调用函数时处理连接的最佳方式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31260279/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com