Tôi có một chuỗi kết nối và tôi muốn có thể xem ra ví dụ "Nguồn dữ liệu". Có một trình phân tích cú pháp, hoặc tôi phải tìm kiếm chuỗi?
Tôi có một chuỗi kết nối và tôi muốn có thể xem ra ví dụ "Nguồn dữ liệu". Có một trình phân tích cú pháp, hoặc tôi phải tìm kiếm chuỗi?
Câu trả lời:
Vâng, có System.Data.Common.DbConnectionStringBuilder
lớp học.
Lớp DbConnectionStringBuilder cung cấp lớp cơ sở mà từ đó các trình xây dựng chuỗi kết nối được gõ mạnh (SqlConnectionStringBuilder, OleDbConnectionStringBuilder, v.v.) xuất phát. Các nhà xây dựng chuỗi kết nối cho phép các nhà phát triển lập trình tạo các chuỗi kết nối chính xác về mặt cú pháp, phân tích và xây dựng lại các chuỗi kết nối hiện có.
Các lớp con quan tâm là:
System.Data.EntityClient.EntityConnectionStringBuilder
System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.OracleClient.OracleConnectionStringBuilder
System.Data.SqlClient.SqlConnectionStringBuilder
Ví dụ: để "xem ra Nguồn dữ liệu" từ chuỗi kết nối máy chủ SQL, bạn có thể làm:
var builder = new SqlConnectionStringBuilder(connectionString);
var dataSource = builder.DataSource;
Có người bán nhà xây dựng chuỗi kết nối cụ thể từ các nhà cung cấp khác nhau như SqlConnectionStringBuilder
, MySqlConnectionStringBuilder
, SQLiteConnectionStringBuilder
vv (tiếc là không có giao diện nào từ MS thời gian này). Nếu không, bạn có DbProviderFactory.CreateConnectionStringBuilder sẽ cung cấp cho bạn một cách khác để viết nó theo cách không liên quan đến nhà cung cấp. Bạn sẽ cần chỉ định nhà cung cấp trong tệp cấu hình và có sẵn phiên bản dll phù hợp. Ví dụ:
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"];
Tôi đã từng viết phân tích thủ công cho bản thân mình mà không gây rắc rối cho tôi. Sẽ rất đơn giản nếu mở rộng điều này để cung cấp thông tin về các tham số khác (hiện tại nó chỉ dành cho những thứ đơn giản như tên db, nguồn dữ liệu, tên người dùng và mật khẩu). Thích cái này hay sao:
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;
}
Đối với điều này, bạn không cần bất cứ điều gì đặc biệt trong tập tin cấu hình, hoặc bất kỳ dll nào cả. Contains
trong Where
mệnh đề chỉ quan trọng nếu bạn cần bỏ qua các kết nối được định dạng kém như server = localhost;pp;
nơi không pp
thêm gì. Để hành xử như những người xây dựng bình thường (sẽ phát nổ trong những trường hợp này) thay đổi Where
thành
.Where(kvp => !string.IsNullOrWhitespace(kvp))
StringComparer.InvariantCultureIgnoreCase
. Xem ToDictionary
tình trạng quá tải
';'
hoặc '='
nhập mật khẩu của họ. Tôi đã viết một triển khai tương tự và học được rằng nó không hoạt động một cách khó khăn. Trời ạ, phân tích chuỗi kết nối thực sự khó hơn tôi nghĩ rất nhiều!
Đây là một vài dòng mã sẽ phân tích bất kỳ chuỗi kết nối nào vào từ điển:
Dictionary<string, string> connStringParts = connString.Split(';')
.Select(t => t.Split(new char[] { '=' }, 2))
.ToDictionary(t => t[0].Trim(), t => t[1].Trim(), StringComparer.InvariantCultureIgnoreCase);
Và sau đó bạn có thể truy cập bất kỳ phần nào:
string dataSource = connStringParts["Data Source"];
StringSplitOptions.RemoveEmptyEntries
cho lần phân chia đầu tiên vì nó sẽ gây ra IndexOutOfRange
ngoại lệ nếu có dấu vết;
SqlConnection
với SqlConnectionStringBuilder
.
Sử dụng SqlConnectionStringBuilder Thật không may, bạn sẽ phải sử dụng một ConnectionStringBuilder cụ thể của DB vì các chuỗi kết nối khác nhau.
Bạn muốn sử dụng DbProviderFactory.CreateConnectionStringBuilder () cung cấp cho bạn trình xây dựng / trình phân tích chuỗi kết nối dành riêng cho trình kết nối của bạn, nhưng không yêu cầu bạn sử dụng bất kỳ lớp cụ thể nào của trình kết nối.
Có, bạn có thể làm điều này bằng cách sử dụng các lớp ConnectionStringBuilder. Dưới đây là danh sách các triển khai DbConnectionStringBuilder có sẵn cho các nhà cung cấp dữ liệu tiêu chuẩn:
System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.OracleClient.OracleConnectionStringBuilder
System.Data.SqlClient.SqlConnectionStringBuilder
đây là ví dụ mẫu về chuỗi kết nối phân tích cú pháp và hiển thị các phần tử của nó.
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);
Bạn có thể sử dụng DbConnectionStringBuilder và bạn không cần bất kỳ nhà cung cấp cụ thể nào:
Các mã sau đây:
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"]);
Đầu ra cho bàn điều khiển:
Data Source: data source value
Server: ServerValue
BIÊN TẬP:
Vì DbConnectionStringBuilder thực hiện IDadata, bạn có thể liệt kê các tham số chuỗi kết nối:
foreach (KeyValuePair<string, object> kv in builder)
{
Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
}
Tôi không thực sự thích tất cả các câu trả lời ở đây. Vì vậy, đây là những gì tôi tìm thấy.
Bạn có thể sử dụng DbConnectionStringBuilder
trực tiếp:
var builder = new System.Data.Common.DbConnectionStringBuilder();
builder.ConnectionString = settings.ConnectionString;
var server = builder["server"];
Vì vậy, tôi thấy tất cả các câu trả lời hiện có ít nhiều sai. Tôi đã kết thúc với giải pháp tầm thường sau đây:
class ConnectionStringParser: DbConnectionStringBuilder {
ConnectionStringParser(string c) { Connection = c; }
public override bool ShouldSerialize(string keyword) => true;
}
Trình phân tích cú pháp nằm trong DbConnectionStringBuilder và khá dễ dàng để truy cập. Điều ngớ ngẩn duy nhất chúng ta phải làm là đặt ShouldSerialize luôn luôn trả về giá trị true để tránh mất các thành phần khi cố gắng thực hiện các chuỗi kết nối tùy ý.
DbConnectionStringBuilder
có các tính năng xử lý chung có thể được sử dụng mà không cần sử dụng các lớp con:if (builder.TryGetValue("Password", out var pwd)) { string decrypted = SomehowDecrypt(pwd); builder["Password"] = decrypted; }