我有一个连接字符串,并且希望能够窥视例如“数据源”。是否有解析器,还是我必须搜索字符串?
我有一个连接字符串,并且希望能够窥视例如“数据源”。是否有解析器,还是我必须搜索字符串?
Answers:
是的,有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;
有来自不同供应商,如供应商特定的连接字符串的建设者SqlConnectionStringBuilder
,MySqlConnectionStringBuilder
,SQLiteConnectionStringBuilder
等(遗憾的是,从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。仅当您需要绕过格式不正确的连接字符串(如where 什么都不添加)时,Contains
in Where
子句才重要。要像正常的生成器一样工作(在这种情况下会爆炸),请将更改为server = localhost;pp;
pp
Where
.Where(kvp => !string.IsNullOrWhitespace(kvp))
StringComparer.InvariantCultureIgnoreCase
。看到ToDictionary
超载
';'
'='
密码或的。我写了一个类似的实现,并了解到它不是很难实现的。天哪,连接字符串解析实际上比我想象的要难得多!
这是几行代码,可以将任何连接字符串解析为字典:
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"];
StringSplitOptions.RemoveEmptyEntries
在第一次拆分中,因为IndexOutOfRange
如果出现拖尾,它将导致异常;
SqlConnection
用SqlConnectionStringBuilder
。
使用SqlConnectionStringBuilder 不幸的是,由于连接字符串不同,您将不得不使用特定于数据库的ConnectionStringBuilder。
您要使用DbProviderFactory.CreateConnectionStringBuilder(),它为您的连接器提供特定的连接字符串生成器/解析器,但不要求您使用任何特定于连接器的类。
是的,您可以使用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);
您可以使用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);
}
因此,我发现所有现有答案或多或少都是错误的。我最终得到了以下简单的解决方案:
class ConnectionStringParser: DbConnectionStringBuilder {
ConnectionStringParser(string c) { Connection = c; }
public override bool ShouldSerialize(string keyword) => true;
}
解析器位于DbConnectionStringBuilder中,非常容易获得。我们要做的唯一愚蠢的事情是将ShouldSerialize设置为始终返回true,以防止在尝试往返任意连接字符串时丢失组件。
DbConnectionStringBuilder
具有可使用的通用处理功能,而无需使用子类:if (builder.TryGetValue("Password", out var pwd)) { string decrypted = SomehowDecrypt(pwd); builder["Password"] = decrypted; }