问题
在 PowerShell 中使用 SqlConnectionStringBuilder 时有一些奇怪的行为 - 让我解释一下
由于它是一个 dotnet 类,因此您会期望 C# 中可用的所有相同属性和方法
例如,这在 C# 中可以正常工作:
var cnnBuilder = new SqlConnectionStringBuilder();
cnnBuilder.DataSource = "server_name";
cnnBuilder.InitialCatalog = "db_name";
所以 PS 中的等效代码,应该工作:
$cnnBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$cnnBuilder.DataSource = "server_name"
$cnnBuilder.InitialCatalog = "db_name"
但是,SqlConnectionStringBuilder 构建在实现 IDictionary 的 DbConnectionStringBuilder 之上,所以从根本上说,我们正在使用具有一些语法糖包装器的字典对象
.NET 用这样的override on the dictionary accessors and setters 解决了这个问题(在此进行了简化):
public override object this[string keyword] {
get {
Keywords index = GetIndex(keyword);
return GetAt(index);
}
set {
Keywords index = GetIndex(keyword);
switch(index) {
case Keywords.DataSource: DataSource = ConvertToString(value); break;
case Keywords.InitialCatalog: InitialCatalog = ConvertToString(value); break;
// ***
}
}
}
真的,它采用DataSource 属性并将其映射到"Data Source" 键(带空格)
每当 PS 分配或检索一个值时,它必须决定是使用底层字典实现还是使用属性。当您在字典中查找DataSource 时(没有空格),sql connection keyword 不存在。
解决方案
选项 1 - 使用字典名称
您可以使用带有实际 sql 键的方括号或点表示法来访问 hashtable 中的条目
$cnnBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$cnnBuilder["Data Source"] = "server_name"
$cnnBuilder."Initial Catalog" = "db_name"
选项 2 - 使用 PSBase
PSBase 返回 "raw view of the object" 并将为我们提供 dotnet 中的默认行为
$cnnBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$cnnBuilder.PSBase.DataSource = "server_name"
$cnnBuilder.PSBase.InitialCatalog = "db_name"
选项 3 - 使用 -Property 参数
在构造过程中,您可以在New-Object 上设置-Property 参数,该参数“设置属性值并调用新对象的方法。”
$cnnBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder `
-Property @{
DataSource = "server_name"
InitialCatalog = "db_name"
}
补充阅读
Using SQLConnection object in PowerShell