Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从控制台应用程序或SQLCLR对象调用函数时,处理连接的最佳方法是使用(";Context connection=true";)_C#_Sql Server_Sqlclr - Fatal编程技术网

C# 从控制台应用程序或SQLCLR对象调用函数时,处理连接的最佳方法是使用(";Context connection=true";)

C# 从控制台应用程序或SQLCLR对象调用函数时,处理连接的最佳方法是使用(";Context connection=true";),c#,sql-server,sqlclr,C#,Sql Server,Sqlclr,我的数据层中有以下类型的代码,可以从控制台应用程序、windows应用程序等调用,并从相应调用方的app.Config文件中读取正确的连接字符串: public静态udsDataset GetDataset(int-datasetID) { 字符串连接字符串= ConfigurationManager.ConnectionString[“ConnectionString”].ConnectionString; 字符串sql=@“从Dataset中选择*,其中DatasetID=@DatasetI

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

public静态udsDataset GetDataset(int-datasetID)
{
字符串连接字符串=
ConfigurationManager.ConnectionString[“ConnectionString”].ConnectionString;
字符串sql=@“从Dataset中选择*,其中DatasetID=@DatasetID”;
使用(SqlConnection conn=newsqlconnection(connectionString))
{
//简洁的查询:
返回conn.Query(sql,new{datasetID}).First();
}    
}
现在,我想从SQLCLR存储过程(在这些表所在的数据库中)调用相同的代码,您通常会在其中使用:

使用(SqlConnection=newsqlconnection(“context connection=true”))
{
connection.Open();
//等等等等等等
}
想到的最明显的方法是重载函数:

public静态udsDataset GetDataset(int-datasetID)
{
字符串连接字符串=
ConfigurationManager.ConnectionString[“ConnectionString”].ConnectionString;
使用(SqlConnection conn=newsqlconnection(connectionString))
{
返回GetDataset(datasetID,conn);
}
}
公共静态udsDataset GetDataset(int-datasetID,SqlConnection-conn)
{
//呼叫方负责关闭和处理连接
字符串sql=@“从Dataset中选择*,其中DatasetID=@DatasetID”;
返回conn.Query(sql,new{datasetID}).First();
}
因此,具有App.Config的应用程序可以调用无连接版本,SQLCLR可以调用需要SqlConnection的版本

这“似乎还可以”,但必须为每个类似的函数编写完全相同的重载样式,这会让人感觉不对劲。

从表面上考虑这个问题(以及对它的评论),为什么需要:

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

??对于
Open
Dispose
,您应该像对待任何其他连接一样对待
上下文连接。听起来您好像在想,当使用连接字符串
“Context Connection=true;”“
”时,只需打开
SqlConnection
,然后在完全打开之前不进行处理,否则您将多次
打开它。我看不出有任何理由在这两种情况下有不同的行为


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

  • 不更改应用程序代码,但依赖一个额外的配置文件:

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

    
    
    SqlContext
    类的属性。只需按如下方式更新原始代码:

    string connectionString=“Context Connection=true;”;;//默认值=SQLCLR连接
    if(!SqlContext.IsAvailable)//如果未在SQL Server中运行,请从配置文件获取
    {
    连接字符串=
    ConfigurationManager.ConnectionString[“CoolioAppDB”]。ConnectionString;
    }
    
    顺便说一句,这种用法在链接的MSDN页面的
    IsAvailable
    属性的“备注”部分有说明


  • 为什么不编写一个metod GetConnection(),并在使用(sqlConnection conn=GetConnection()){}的所有地方使用它呢?GetConnection metod应该处理connectionstring,这样代码的其余部分就不必关心它了。这在理论上不会失去保证连接处理的优势吗?无论如何,当从SQLCLR过程调用时,我仍然需要传入现有连接的选项。不,该方法应该在每次调用时创建一个新连接,并且围绕它的Using()正在处理处理该处理,因此没有问题。选项#2看起来最吸引人,但要么我解释得不好,要么我误解了什么。包含GetDataset()的DLL可能正在SQL Server中运行,也可能没有运行,它可能只是部署到常规windows桌面上。我是否只需要将“使用Microsoft.SqlServer.Server”添加到该类中,然后我就可以了????因此,如果SqlContext.IsAvailable==true,则使用:connectionString=“Context Connection=true;”;如果不是,则从配置文件中读取连接字符串(这只会在不在SQL Server中运行时发生,因此我不需要在SQL Server中安装配置),假设它为true,我只需要添加“使用”,那么这个逻辑就可以被封装在一个GetConnectionString函数中,然后各个方法就不需要知道这个了,很好。@t在这里回答您的第一个评论:是的,这正是选项2的全部内容。只需使用Microsoft.SqlServer.Server添加
    以便您可以测试
    SqlContext.IsAvailable
    。无论DLL安装在何处,我发布的代码都可以工作。同样,在“备注”部分的MSDN页面中也提倡使用这个确切的用例。第二点:是的,您可以将其封装到一个通用的
    GetConnectionString
    方法中。哦,是的,很漂亮:-)。太好了,再次感谢@srutzky,你似乎回答了我一半的问题!:)