正在检查SQL连接字符串是否指定了参数



如果给定的SQL连接字符串显式指定了某个参数,例如";Encrypt=...";。我尝试使用SqlConnectionStringBuilder解析字符串,希望ContainsKey()能告诉我是否指定了密钥,但它不起作用:

System.Data.SqlClient.SqlConnectionStringBuilder x = 
new("Data Source=.;Initial Catalog=myDb;Integrated Security=True");
bool encryptSpecified = x.ContainsKey("Encrypt"); // returns true :(

澄清

我应该澄清为什么我需要知道是否明确指定了Encrypt参数。在当前版本的Microsoft.Data.SqlClient中,Encrypt的默认值为true,但在此之前(在Sql.Data.SqlClient中(为false。因此,为了确保升级到Microsoft.Data.SqlClient后应用程序的向后兼容性,我希望将Encrypt参数设置为false,除非用户明确为其指定值

解决方案

[基于与@Charlieface的讨论]

// important: *not* Microsoft.Data.SqlClient.SqlConnectionStringBuilder!
System.Data.SqlClient.SqlConnectionStringBuilder scsb = 
new(connectionString); 
if (!scsb.Encrypted) scsb.Encrypted = false; // this will explicitly set Encrypt
connectionString = scsb.ConnectionString;

ContainsKey基本上是无用的,因为它只是告诉您是否支持某个键,而不是字符串是否真的包含该键。如果字符串没有该键,则使用默认值。

您只需使用Encrypt属性来告诉您值是什么。如果默认值为false(在新版Microsoft.Data.SqlClient中已更改为true(,则会返回false

此外,这比检查字符串是否包含键更有用,因为它"告诉"您在运行时实际使用的值。

var x = new SqlConnectionStringBuilder("Data Source=.;Initial Catalog=myDb;Integrated Security=True");
Console.WriteLine(x.ContainsKey("Encrypt"));

dotnetfiddle

出于同样的原因,我遇到了同样的问题。我们在小型内部网络上安装了大量SQL Server,因此我们更倾向于保留Encrypt=false的旧默认行为。仅仅因为微软更改了默认值,就不值得在所有这些机器上为证书烦恼。在我们拥有云托管数据库的极少数情况下,我们将在服务器上显式配置证书并设置Encrypt=true。

我不想继续使用旧的System.Data.SqlClient.SqlConnectionStringBuilder类型(正如问题的解决方案所建议的那样(,因为我的Directory.Packages.rops文件不再允许引用System.Data.SqlClient包。

我的解决方法使用一个简单的正则表达式:

using Microsoft.Data.SqlClient;
...
SqlConnectionStringBuilder builder = new(connectionString);
Regex containsEncrypt = CreateContainsEncryptRegex();
if (!containsEncrypt.IsMatch(connectionString))
{
builder.Encrypt = false;
}
connectionString = builder.ConnectionString;
...
[GeneratedRegex(@"(?i)(^|;)s*Encrypts*=", RegexOptions.Compiled)]
private static partial Regex CreateContainsEncryptRegex();

相关内容

  • 没有找到相关文章

最新更新