क्या C # में कोई कनेक्शन स्ट्रिंग पार्सर है?


181

मेरे पास एक कनेक्शन स्ट्रिंग है और मैं उदाहरण के लिए "डेटा स्रोत" को देखने में सक्षम होना चाहता हूं। क्या कोई पार्सर है, या मुझे स्ट्रिंग की खोज करनी है?

जवाबों:


305

हाँ, वहाँ 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

उदाहरण के लिए, एसक्यूएल-सर्वर कनेक्शन स्ट्रिंग से "डेटा स्रोत को झांकना", आप कर सकते हैं:

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

6
बेस क्लास DbConnectionStringBuilderमें जेनेरिक प्रोसेसिंग फीचर्स होते हैं जिनका उपयोग उपवर्गों का उपयोग किए बिना किया जा सकता है:if (builder.TryGetValue("Password", out var pwd)) { string decrypted = SomehowDecrypt(pwd); builder["Password"] = decrypted; }
ओलिवियर जैकोट-डेसॉम्ब्स

41

विक्रेता की तरह विभिन्न प्रदाताओं से विशिष्ट कनेक्शन स्ट्रिंग बिल्डरों रहे हैं SqlConnectionStringBuilder, MySqlConnectionStringBuilder, SQLiteConnectionStringBuilderआदि (दुर्भाग्य से वहाँ एमएस इस समय से कोई सार्वजनिक इंटरफ़ेस है)। अन्यथा आपके पास DbProviderFactory.CreateConnectionStringBuilder है जो आपको इसे प्रदाता-अज्ञेय तरीके से लिखने का एक वैकल्पिक तरीका देगा। आपको कॉन्फ़िगरेशन फ़ाइल में प्रदाता निर्दिष्ट करना होगा और डीएलएल का सही संस्करण उपलब्ध होगा। उदाहरण के लिए,

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;
}

इसके लिए आपको कॉन्फिग फाइल या किसी डीएलएल में कुछ खास करने की जरूरत नहीं है। Containsमें Whereखंड महत्वपूर्ण केवल यदि आप बाईपास के लिए की तरह खराब स्वरूपित ConnectionStrings की जरूरत है server = localhost;pp;, जहां ppकुछ भी नहीं करने के लिए कहते हैं। सामान्य बिल्डरों की तरह व्यवहार करने के लिए (जो इन मामलों में विस्फोट होगा) को बदल देते Whereहैं

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

@Icarus वास्तव में नहीं है क्योंकि शब्दकोश की कुंजी तुलनाकर्ता है StringComparer.InvariantCultureIgnoreCaseToDictionaryअधिभार देखें
nawfal

1
हाँ, आप सही हैं, मैंने अभी एक त्वरित परीक्षण लिखा है। गलत होने के बाद से मेरी मूल टिप्पणी हटा दी जाएगी।
इकारस

3
आपका getValue () विधि मामलों में जहां उदाहरण के लिए उपयोगकर्ता एक है में काम नहीं करेगा ';'या एक '='अपने पासवर्ड में। मैंने एक समान कार्यान्वयन लिखा था और सीखा कि यह कठिन काम नहीं करता है। गोश, कनेक्शन स्ट्रिंग पार्सिंग वास्तव में बहुत कठिन है जितना मैंने सोचा था!
फिलिप Atz

@ जोशुआ मुझे आशा है कि आप मैनुअल पार्सिंग भाग के बारे में बात कर रहे हैं। कृपया यहां एक प्रारंभिक बिंदु के रूप में उत्तर दें, जो मूर्खतापूर्ण और युद्ध-परीक्षण किए गए समाधानों के बजाय काम किया जा सकता है। मुझे आशा है कि वे टिप्पणियों से अधिक मूल्यवान हैं जो कोई जानकारी नहीं छोड़ते हैं। आप डाउनवोट होने के लिए भी स्वतंत्र हैं। जहां तक ​​मुझे पता है, आगे जो भी करने की जरूरत है, वह है मानकों का पालन करना। MS के पास msdn पर एक है और यह मेरे दिमाग में लंबे समय से अमेंडेंड है। अगर केवल हम सभी के पास समय होता। '' 'सभी कृपया किनारे के मामलों को ध्यान में रखें, जो कि फिलिप एट्ज़ की टिप्पणी में एक है।
नवाफाल

@nawfal: एक बार हल करने के बाद मैं चारों ओर आया और एक उत्तर छोड़ दिया।
जोशुआ

15

यहाँ कोड की कुछ पंक्तियाँ हैं जो किसी भी कनेक्शन स्ट्रिंग को एक शब्दकोश में पार्स करेंगे:

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

3
स्मार्ट, केवल एक चीज जिसे मैं बदलूंगा, वह StringSplitOptions.RemoveEmptyEntriesपहले विभाजन में शामिल होगी क्योंकि यह एक IndexOutOfRangeअपवाद का कारण होगा यदि कोई अनुगामी हो;
स्कॉट चैंबरलेन

2
यह काम करता है, लेकिन कनेक्शन स्ट्रिंग बिल्डर्स अधिक मजबूत हैं। इस तरह का कोड अमान्य कनेक्शन स्ट्रिंग के मामले में अधिक सार्थक पार्सिंग त्रुटियों के बजाय निम्न-स्तरीय अपवादों को फेंक देगा।
सैम

इससे मुझे ADO कनेक्शन स्ट्रिंग को पार्स करने में मदद मिली, ताकि मैं इसके SqlConnectionसाथ एक समकक्ष बना सकूं SqlConnectionStringBuilder
होलिस्टिक डेवलपर

कुछ कैविएट यहाँ। कनेक्शन स्ट्रिंग मान को उद्धरणों में संलग्न किया जा सकता है, उदाहरण के लिए।
सेवा अलेक्सेयेव

6

SqlConnectionStringBuilder का उपयोग करें दुर्भाग्य से आपको कनेक्शन स्ट्रिंग्स अलग होने के कारण DB विशिष्ट कनेक्शनस्ट्रिंगबर्स्ट का उपयोग करना होगा।


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

4

आप 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 एप्लाइड IDEDIA आप कनेक्शन स्ट्रिंग मापदंडों की गणना कर सकते हैं:

foreach (KeyValuePair<string, object> kv in builder)
{
    Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
}

यह आपको पहले से ही पता है कि कनेक्शन स्ट्रिंग में एक "डेटा स्रोत" मान आदि है, जो हमेशा सही नहीं होता है, जैसा कि स्टैकओवरफ्लो. com /a/ 15529085 / 534109 , में उल्लेख किया गया है।
टिसन टी।

मेरा जवाब विशेष रूप से पूछता है कि ऑप क्या पूछता है: 'मैं उदाहरण के लिए "डेटा स्रोत" को देखने में सक्षम होना चाहता हूं
जेसुएस लोपेज

मैंने इसे सभी कनेक्शन स्ट्रिंग मापदंडों को दिखाने के लिए संपादित किया।
जेसुएस लोपेज़

1

मैं वास्तव में यहाँ सभी जवाब पसंद नहीं आया। तो यहाँ मैं क्या पाया है।

.NET कोर के साथ

आप 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 में है और बहुत आसान है। केवल मूर्खतापूर्ण चीज जो हमें करनी है वह है सेटस्लैरीज़ को हमेशा सही खोने के लिए घटकों को खोने से रोकने के लिए जब ट्रिप ट्रिप मनमाने ढंग से कनेक्शन स्ट्रिंग्स की कोशिश कर रहे हों।


2
मौजूदा उत्तरों में क्या गलत था? या आपका समाधान क्या तय करता है स्पष्टीकरण सहायक होगा।
नवाफाल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.