2011-01-26 148 views

回答

262

是的,还有的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; 
5

使用SqlConnectionStringBuilder 不幸的是,你将不得不使用DB特定ConnectionStringBuilder作为连接字符串迪菲河

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); 
30

有来自不同供应商的供应商特定的连接字符串助洗剂等SqlConnectionStringBuilderMySqlConnectionStringBuilderSQLiteConnectionStringBuilder等(遗憾的是从MS此时没有公共接口)。否则,你有DbProviderFactory.CreateConnectionStringBuilder这将给你一个替代方式来写它提供者不可知的方式。您需要在配置文件中指定提供程序,并提供适当的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。 ContainsWhere条款是很重要的,如果只需要绕过像server = localhost;pp;格式混乱的ConnectionStrings其中pp增加了什么。要表现得像普通建设者(这将在这些情况下爆炸)更改代码的Where

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

@Icarus不是真的,因为字典的键比较器是`StringComparer.InvariantCultureIgnoreCase`。看到`ToDictionary`超载 – nawfal 2013-03-21 20:03:44

+1

是的,你是对的,我只是写了一个快速测试。将删除我原来的评论,因为它是错误的。 – Icarus 2013-03-21 20:51:04

+2

您的GetValue()方法在例如用户的密码中包含“;”或“=”的情况下不起作用。我写了一个类似的实现,并了解到它不会以困难的方式工作。天哪,连接字符串解析实际上比我想象的要困难得多! – 2015-12-10 14:59:45

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"]; 
2

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

所以我发现了所有的存在答案或多或少都是错误的。我结束了以下平凡解:

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

解析器是DbConnectionStringBuilder和非常容易得到的。我们必须做的唯一愚蠢的事情是将ShouldSerialize设置为始终返回true以防止在尝试绕过任意连接字符串时丢失组件。