ฉันมีสตริงการเชื่อมต่อและฉันต้องการที่จะมองออกไปเช่น "แหล่งข้อมูล" มีตัวแยกวิเคราะห์หรือฉันต้องค้นหาสตริงหรือไม่
ฉันมีสตริงการเชื่อมต่อและฉันต้องการที่จะมองออกไปเช่น "แหล่งข้อมูล" มีตัวแยกวิเคราะห์หรือฉันต้องค้นหาสตริงหรือไม่
คำตอบ:
ใช่มี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"];
ฉันเคยเขียนคู่มือการแยกวิเคราะห์สำหรับตัวเองซึ่งไม่ได้ทำให้ฉันมีปัญหาใด ๆ มันจะไม่สำคัญที่จะขยายสิ่งนี้เพื่อให้ข้อมูลเกี่ยวกับพารามิเตอร์อื่น ๆ (ตอนนี้มันเป็นเพียงสำหรับสิ่งง่าย ๆ เช่นชื่อ 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;
}
สำหรับสิ่งนี้คุณไม่ต้องการอะไรเป็นพิเศษในไฟล์ config หรือ dll ใด ๆ เลย Containsใน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 เฉพาะของ DB เนื่องจากสตริงการเชื่อมต่อแตกต่างกัน
คุณต้องการใช้DbProviderFactory.CreateConnectionStringBuilder ()ซึ่งให้ตัวสร้างสตริงการเชื่อมต่อ / parser เฉพาะสำหรับตัวเชื่อมต่อของคุณ แต่ไม่ต้องการให้คุณใช้คลาสเฉพาะของตัวเชื่อมต่อใด ๆ
ใช่คุณสามารถทำได้โดยใช้คลาส 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);
}
ฉันไม่ชอบคำตอบทั้งหมดที่นี่ ดังนั้นนี่คือสิ่งที่ฉันพบ
คุณสามารถใช้DbConnectionStringBuilderโดยตรง:
var builder = new System.Data.Common.DbConnectionStringBuilder();
builder.ConnectionString = settings.ConnectionString;
var server = builder["server"];
ดังนั้นฉันจึงพบว่าคำตอบที่มีอยู่ทั้งหมดนั้นผิดไปมากหรือน้อย ฉันสิ้นสุดด้วยวิธีแก้ปัญหาเล็กน้อยต่อไปนี้:
class ConnectionStringParser: DbConnectionStringBuilder {
ConnectionStringParser(string c) { Connection = c; }
public override bool ShouldSerialize(string keyword) => true;
}
parser อยู่ใน DbConnectionStringBuilder และง่ายมากที่จะไปที่ สิ่งเดียวที่เราต้องทำคือการตั้งค่า ShouldSerialize ให้คืนค่าจริงเสมอเพื่อป้องกันการสูญเสียส่วนประกอบเมื่อพยายามที่จะเดินทางไปรอบ ๆ สตริงการเชื่อมต่อโดยพลการ
DbConnectionStringBuilderมีคุณสมบัติการประมวลผลทั่วไปที่สามารถใช้ได้โดยไม่ต้องใช้คลาสย่อย:if (builder.TryGetValue("Password", out var pwd)) { string decrypted = SomehowDecrypt(pwd); builder["Password"] = decrypted; }