DbConnectionStringBuilder не анализируется при использовании в PowerShell - PullRequest
6 голосов
/ 04 июня 2011

Я пытаюсь использовать возможности DbConnectionStringBuilder для анализа пользовательского ввода в виде строки подключения.Это прекрасно работает в C #:

using System;
using System.Data.Common;
class Program
{
    static void Main(string[] args)
    {
        var sb = new DbConnectionStringBuilder();
        sb.ConnectionString = "server = 'smtp.gmail.com'; port = 587; user = you@gmail.com";
        Console.WriteLine(sb["server"]);
        Console.WriteLine(sb["port"]);
        Console.WriteLine(sb["user"]);
    }
}

Вывод:

smtp.gmail.com
587
you@gmail.com

Но в PowerShell это не работает.А именно, этот буквально переведенный код в PowerShell

$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.ConnectionString = "server = 'smtp.gmail.com'; port = 587; user = you@gmail.com"
$sb["server"]
$sb["port"]
$sb["user"] 

не производит вообще никакого вывода.

Есть идеи почему?Как заставить DbConnectionStringBuilder работать как анализатор в PowerShell?

Ответы [ 3 ]

5 голосов
/ 04 июня 2011

System.Data.Common.DbConnectionStringBuilder реализует IDictionary. В Powershell есть сокращение для словарей, использующих ., которое позволяет извлекать и назначать пары ключ / значение, как если бы ключ был свойством:

$dict = @{}
$dict["key1"] = 'value1'
$dict.key2 = 'value2'

Вы видите, что она сохраняет всю строку подключения в виде пары ключ / значение, а не в свойстве ConnectionString следующим образом:

$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.ConnectionString = "server = 'smtp.gmail.com'; port = 587; user = you@gmail.com"
$sb #formatted table of key/value pairs

Самый простой способ обойти это - вызвать методы set_ / get_, сгенерированные для свойств:

$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.set_ConnectionString("server = 'smtp.gmail.com'; port = 587; user = you@gmail.com")
$sb["server"]
$sb["port"]
$sb["user"]
4 голосов
/ 04 июня 2011

Вероятно, это ошибка (в любом случае, я пойму), и я скоро ее отправлю. Похоже, что PowerShell не вызывает сеттеры для свойств классов, которые реализуют IDictionary (как это делает DbConnectionStringBuilder, и это сеттер ConnectionString, который анализирует строку).

Вот две демонстрации (оригинал и обходной путь):

# test 1 - does not work, presumably PowerShell invokes $sb["ConnectionString"] = .. instead of the setter
$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.ConnectionString = "server = 'smtp.gmail.com'; port = 587; user = you@gmail.com"

# the original string
$sb.ConnectionString

# nothing at all
$sb["server"]
$sb["port"]
$sb["user"]

# test 2 - works fine, we make PowerShell to invoke the ConnectionString property setter in this way
$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.PSObject.Properties['ConnectionString'].Value = "server = 'smtp.gmail.com'; port = 587; user = you@gmail.com"

# parsed and re-formatted string
$sb.ConnectionString

# parsed data
$sb["server"]
$sb["port"]
$sb["user"]

Выход:

server = 'smtp.gmail.com'; port = 587; user = you@gmail.com
server=smtp.gmail.com;port=587;user=you@gmail.com
smtp.gmail.com
587
you@gmail.com

Поскольку обходной путь найден, мы бесплатно получаем довольно мощный анализатор для данных, похожих на строки подключения. Вот демонстрация, которая показывает разбор довольно запутанного ввода:

# get the parser
$sb = New-Object System.Data.Common.DbConnectionStringBuilder

# input the string to parse using this workaround way
$sb.PSObject.Properties['ConnectionString'].Value = @'
Apostrophes = "Some 'value'";
Quotations = 'Some "value"';
Semicolons = '1; 2; 3';
Multiline = Line1
Line2
Line3;
Name with spaces = Some value;
Name with == sign = Some value;
'@

# get the parsed results

# the string: not the original but parsed and re-formatted
$sb.ConnectionString

# the data: parsed key/values
$sb | Format-Table -AutoSize -Wrap

Выход:

apostrophes="Some 'value'";quotations='Some "value"';semicolons="1; 2; 3";multiline="Line1
Line2
Line3";name with spaces="Some value";name with == sign="Some value"

Key              Value              
---              -----              
apostrophes      Some 'value'       
quotations       Some "value"       
semicolons       1; 2; 3            
multiline        Line1              
                 Line2              
                 Line3              
name with spaces Some value         
name with = sign Some value         
0 голосов
/ 04 июня 2011
$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.Add("server","smtp.gmail.com")
$sb.Add("port",587)
$sb.Add("user","you@gmail.com")

$sb["server"]
$sb["port"]
$sb["user"] 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...