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

问题描述 投票:170回答:9

我有一个连接字符串,我希望能够查看例如“数据源”。有解析器,还是我必须搜索字符串?

c# .net
9个回答
282
投票

是的,有System.Data.Common.DbConnectionStringBuilder类。

DbConnectionStringBuilder类提供基类,强类型连接字符串构建器(SqlConnectionStringBuilder,OleDbConnectionStringBuilder等)派生自该基类。连接字符串构建器允许开发人员以编程方式创建语法正确的连接字符串,并解析和重建现有的连接字符串。

感兴趣的子类是:

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

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

var builder = new SqlConnectionStringBuilder(connectionString);
var dataSource = builder.DataSource;

32
投票

来自各种提供商的供应商特定连接字符串构建器,如SqlConnectionStringBuilderMySqlConnectionStringBuilderSQLiteConnectionStringBuilder等(遗憾的是,这次没有来自MS的公共接口)。否则你有DbProviderFactory.CreateConnectionStringBuilder,它将为你提供另一种方式来编写与提供者无关的方式。您需要在配置文件中指定provider并提供正确的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"];

我曾经为自己编写了手动解析,但没有给我任何麻烦。扩展它以提供其他参数的信息是微不足道的(现在它仅用于简单的事情,如数据库名称,数据源,用户名和密码)。像这样左右:

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中都不需要任何特殊功能。 Contains条款中的Where只有在你需要绕过server = localhost;pp;格式错误的连接线时才很重要,pp在这里没有任何东西。为了像普通的建造者(在这些情况下会爆炸)一样,将Where改为

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

11
投票

这里有几行代码可以将任何连接字符串解析为字典:

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

然后你可以访问任何部分:

string dataSource = connStringParts["Data Source"];

6
投票

使用SqlConnectionStringBuilder不幸的是,您必须使用特定于DB的ConnectionStringBuilder,因为连接字符串不同。


6
投票

您希望使用DbProviderFactory.CreateConnectionStringBuilder (),它为您提供特定于连接器的连接字符串构建器/解析器,但不要求您使用任何特定于连接器的类。


4
投票

是的,您可以使用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);

3
投票

您可以使用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);
}

1
投票

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

使用.NET Core

您可以直接使用DbConnectionStringBuilder

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

0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.