如何使用 PowerShell 从 Connectionstring 获取数据源?

Sam*_*abu 5 .net sql powershell

在.Net中,我们可以使用以下机制从连接字符串获取数据源:

System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder(connectionString);

string server = builder.DataSource;
Run Code Online (Sandbox Code Playgroud)

我试图在 PowerShell 中执行此操作,但出现以下异常:

$ConstringObj = New-Object System.Data.SqlClient.SqlConnectionStringBuilder($conString)
Run Code Online (Sandbox Code Playgroud)

New-Object:使用“1”个参数调用“.ctor”时出现异常:“不支持关键字:‘元数据’。” 在第 1 行:17 + $ConstringObj = New-Object System.Data.SqlClient.SqlConnectionStringBuilder($con ... + ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 类别信息:无效操作:(:) [新对象],MethodInitationException + FullQualifiedErrorId:ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

如何在 PowerShell 中执行此操作?

Kyl*_*Mit 13

解决方案

选项 A - 使用字典名称

您可以使用括号或点符号与实际的 sql 键来访问哈希表中的条目

$cnnBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$cnnBuilder["Data Source"] = "server_name"
$cnnBuilder."Initial Catalog" = "db_name"
Run Code Online (Sandbox Code Playgroud)

选项 B - 使用PSBase

PSBase返回“对象的原始视图”,并将为我们提供 dotnet 中的默认行为

$cnnBuilder  = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$cnnBuilder.PSBase.DataSource = "server_name"
$cnnBuilder.PSBase.InitialCatalog = "db_name"
Run Code Online (Sandbox Code Playgroud)

选项 C - 使用-Property参数

在构造过程中,您可以设置“设置属性值并调用新对象的方法”的参数-PropertyNew-Object

$cnnBuilder  = New-Object System.Data.SqlClient.SqlConnectionStringBuilder `
    -Property @{
        DataSource = "server_name"
        InitialCatalog = "db_name"
    }
Run Code Online (Sandbox Code Playgroud)

解释

在 PowerShell 中使用时出现一些奇怪的行为SqlConnectionStringBuilder- 让我解释一下

由于它是一个 dotnet 类,因此您期望 C# 中提供所有相同的属性和方法

例如,这在 C# 中运行良好:

var cnnBuilder = new SqlConnectionStringBuilder();
cnnBuilder.DataSource = "server_name";
cnnBuilder.InitialCatalog = "db_name";
Run Code Online (Sandbox Code Playgroud)

所以 PS 中的等效代码应该可以工作:

$cnnBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$cnnBuilder.DataSource = "server_name"
$cnnBuilder.InitialCatalog = "db_name"
Run Code Online (Sandbox Code Playgroud)

然而,它是建立在其实现SqlConnectionStringBuilder之上的,所以从根本上来说,我们正在使用一个具有一些语法糖包装器的字典对象DbConnectionStringBuilderIDictionary

.NET 通过重写字典访问器和设置器来解决此问题(此处进行了简化):

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;
            // ***
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以实际上,它正在获取DataSource属性并将其映射到"Data Source" 带空格

internal static class DbConnectionStringKeywords {
    internal const string DataSource = "Data Source";
}
Run Code Online (Sandbox Code Playgroud)

每当 PS 分配或检索一个值时,它必须决定是否使用底层字典实现或属性。当您在字典中查找DataSource(不带空格)时,该sql 连接关键字不存在。

补充阅读