Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.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#中是否有连接字符串解析器?_C#_.net - Fatal编程技术网

C#中是否有连接字符串解析器?

C#中是否有连接字符串解析器?,c#,.net,C#,.net,我有一个连接字符串,我希望能够窥视例如“数据源”。 有解析器吗,或者我必须搜索字符串吗?是的,有类 DbConnectionStringBuilder类 提供基类,其中 强类型连接字符串 构建器(SqlConnectionStringBuilder, OleDbConnectionStringBuilder等 (在)派生。连接字符串 建设者让开发者 以编程方式按语法创建 正确的连接字符串,并解析 并重建现有连接 字符串 感兴趣的子类包括: System.Data.EntityClient.Ent

我有一个连接字符串,我希望能够窥视例如“数据源”。 有解析器吗,或者我必须搜索字符串吗?

是的,有类

DbConnectionStringBuilder类 提供基类,其中 强类型连接字符串 构建器(SqlConnectionStringBuilder, OleDbConnectionStringBuilder等 (在)派生。连接字符串 建设者让开发者 以编程方式按语法创建 正确的连接字符串,并解析 并重建现有连接 字符串

感兴趣的子类包括:

System.Data.EntityClient.EntityConnectionStringBuilder
System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.OracleClient.OracleConnectionStringBuilder
System.Data.SqlClient.SqlConnectionStringBuilder

例如,要从SQL server连接字符串中“查看数据源”,可以执行以下操作:

var builder = new SqlConnectionStringBuilder(connectionString);
var dataSource = builder.DataSource;
使用
不幸的是,由于连接字符串不同,您必须使用特定于DB的ConnectionStringBuilder。

您想使用它,它为您提供特定于连接器的连接字符串生成器/解析器,但不要求您使用任何特定于连接器的类。

是的,您可以使用ConnectionStringBuilder类执行此操作。 以下是标准数据提供程序的可用DbConnectionStringBuilder实现列表:

System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.OracleClient.OracleConnectionStringBuilder
System.Data.SqlClient.SqlConnectionStringBuilder
下面是解析连接字符串并显示其元素的示例

 string conString = @"Data Source=.\sqlexpress;" +
                        "Database=Northwind;Integrated Security=SSPI;" +
                        "Min Pool Size=5;Max Pool Size=15;Connection Reset=True;" +
                        "Connection Lifetime=600;";
    // Parse the SQL Server connection string and display it's properties

    SqlConnectionStringBuilder objSB1 = new SqlConnectionStringBuilder(conString);
    Response.Write("<b>Parsed SQL Connection String Parameters:</b>");
    Response.Write(" <br/>  Database Source = " + objSB1.DataSource);
    Response.Write(" <br/>  Database = " + objSB1.InitialCatalog);
    Response.Write(" <br/>  Use Integrated Security = " + objSB1.IntegratedSecurity);
    Response.Write(" <br/>  Min Pool Size = " + objSB1.MinPoolSize);
    Response.Write(" <br/>  Max Pool Size = " + objSB1.MaxPoolSize);
    Response.Write(" <br/>  Lifetime = " + objSB1.LoadBalanceTimeout);
string conString=@“数据源=。\sqlexpress+
“数据库=北风;集成安全=SSPI;”+
“最小池大小=5;最大池大小=15;连接重置=真;”+
“连接寿命=600;”;
//解析SQL Server连接字符串并显示其属性
SqlConnectionStringBuilder objSB1=新SqlConnectionStringBuilder(构造);
Write(“解析的SQL连接字符串参数:”);
Response.Write(“
数据库源=“+objSB1.DataSource”); Response.Write(“
数据库=“+objSB1.InitialCatalog”); 响应。写入(“
使用集成安全性=“+objSB1.IntegratedSecurity”); Write(“
最小池大小=“+objSB1.MinPoolSize”); Write(“
最大池大小=“+objSB1.MaxPoolSize”); Response.Write(“
lifety=“+objSB1.LoadBalanceTimeout”);
有来自不同提供商的特定于供应商的连接字符串生成器,如
SqlConnectionStringBuilder
MySqlConnectionStringBuilder
SQLiteConnectionStringBuilder
等(不幸的是,这次MS没有公共接口)。否则,您将有一个替代方法来编写它,它与提供者无关。您需要在配置文件中指定提供程序,并提供正确版本的dll。例如

var c = "server=localhost;User Id=root;database=ppp";
var f = DbProviderFactories.GetFactory("MySql.Data.MySqlClient"); //your provider
var b = f.CreateConnectionStringBuilder();
b.ConnectionString = c;
var s = b["data source"];
var d = b["database"];
我曾经为自己编写过手动解析,这并没有给我带来任何麻烦。扩展它以提供关于其他参数的信息(目前它只用于简单的事情,如db名称、数据源、用户名和密码)是很简单的。大概是这样的:

static readonly string[] serverAliases = { "server", "host", "data source", "datasource", "address", 
                                           "addr", "network address" };
static readonly string[] databaseAliases = { "database", "initial catalog" };
static readonly string[] usernameAliases = { "user id", "uid", "username", "user name", "user" };
static readonly string[] passwordAliases = { "password", "pwd" };

public static string GetPassword(string connectionString)
{
    return GetValue(connectionString, passwordAliases);
}

public static string GetUsername(string connectionString)
{
    return GetValue(connectionString, usernameAliases);
}

public static string GetDatabaseName(string connectionString)
{
    return GetValue(connectionString, databaseAliases);
}

public static string GetServerName(string connectionString)
{
    return GetValue(connectionString, serverAliases);
}

static string GetValue(string connectionString, params string[] keyAliases)
{
    var keyValuePairs = connectionString.Split(';')
                                        .Where(kvp => kvp.Contains('='))
                                        .Select(kvp => kvp.Split(new char[] { '=' }, 2))
                                        .ToDictionary(kvp => kvp[0].Trim(),
                                                      kvp => kvp[1].Trim(),
                                                      StringComparer.InvariantCultureIgnoreCase);
    foreach (var alias in keyAliases)
    {
        string value;
        if (keyValuePairs.TryGetValue(alias, out value))
            return value;
    }
    return string.Empty;
}
为此,您不需要任何特殊的配置文件,或任何dll在所有
中包含
,其中
子句仅在您需要绕过格式不良的连接字符串(如
server=localhost)时才很重要;聚丙烯其中
pp
不添加任何内容。要像普通构建器一样工作(在这些情况下会爆炸),请将
Where
更改为

.Where(kvp => !string.IsNullOrWhitespace(kvp))

下面是将任何连接字符串解析到字典中的几行代码:

Dictionary<string, string> connStringParts = connString.Split(';')
    .Select(t => t.Split(new char[] { '=' }, 2))
    .ToDictionary(t => t[0].Trim(), t => t[1].Trim(), StringComparer.InvariantCultureIgnoreCase);

您可以使用DbConnectionStringBuilder,并且不需要任何特定的提供程序:

以下代码:

var cnstr = "Data Source=data source value;Server=ServerValue";
var builder = new DbConnectionStringBuilder();
builder.ConnectionString = cnstr;
Console.WriteLine("Data Source: {0}", builder["Data Source"]);
Console.WriteLine("Server: {0}", builder["Server"]);
控制台的输出:

Data Source: data source value
Server: ServerValue
编辑:

由于DbConnectionStringBuilder实现IDictionary,因此可以枚举连接字符串参数:

foreach (KeyValuePair<string, object> kv in builder)
{
    Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
}
foreach(生成器中的KeyValuePair)
{
Console.WriteLine(“{0}:{1}”,kv.Key,kv.Value);
}

所以我发现所有现有的答案或多或少都是错的。我最终得到了以下简单的解决方案:

class ConnectionStringParser: DbConnectionStringBuilder {
    ConnectionStringParser(string c) { Connection = c; }
    public override bool ShouldSerialize(string keyword) => true;
}

解析器位于DbConnectionStringBuilder中,非常容易获取。我们要做的唯一愚蠢的事情就是将ShouldSerialize设置为始终返回true,以防止在尝试往返任意连接字符串时丢失组件。

我并不喜欢这里的所有答案。这就是我的发现

具有.NET内核 您可以直接使用
DbConnectionStringBuilder

var builder = new System.Data.Common.DbConnectionStringBuilder();
builder.ConnectionString = settings.ConnectionString;
var server = builder["server"];

@Icarus不是真的,因为字典的关键比较器是
StringComparer.InvariantCultureInogoreCase
。查看
ToDictionary
overloading是的,你是对的,我刚刚写了一个快速测试。将删除我的原始注释,因为它是错误的。例如,如果用户有一个
”;,则GetValue()方法将不起作用
'='
。我已经编写了一个类似的实现,并且了解到它并不是很难实现的。天哪,连接字符串解析实际上比我想象的要困难得多@Joshua我希望你说的是手动解析部分。请把这里的答案作为一个起点,而不是万无一失、经过战斗考验的解决方案。我希望它们比没有留下任何信息的评论更有价值。你也可以自由投反对票。据我所知,需要进一步做的是遵守解析标准。MS在msdn上有一个,这在我的脑海中已经很久了。要是我们都有时间就好了。“@”请记住边缘情况,尤其是Philip Atz的评论中的情况。@nawfal:我解决了它后,留下了一个答案。聪明的是,我唯一要改变的是include
StringSplitOptions。将mptyentries
删除到第一次拆分,因为如果有尾随
,它将导致
索引自动转换
异常这是可行的,但是连接字符串生成器更健壮。在连接字符串无效的情况下,这样的代码将抛出低级异常,而不是更有意义的解析错误。这有助于我解析ADO连接字符串,以便构建等效的SqlConnectionwi
var builder = new System.Data.Common.DbConnectionStringBuilder();
builder.ConnectionString = settings.ConnectionString;
var server = builder["server"];