2011-01-26 26 views

Respuesta

262

Sí, está la clase System.Data.Common.DbConnectionStringBuilder.

clase El DbConnectionStringBuilder proporciona la clase base desde la cual los inflexible cadena de conexión constructores (SqlConnectionStringBuilder, OleDbConnectionStringBuilder, y así sucesivamente) derivan. Los constructores de cadena de conexión permiten a los desarrolladores crear mediante programación sintácticamente cadenas de conexión correctas, y analizar y reconstruir las cadenas de conexión existentes .

Las subclases de interés son:

System.Data.EntityClient.EntityConnectionStringBuilder 
System.Data.Odbc.OdbcConnectionStringBuilder 
System.Data.OleDb.OleDbConnectionStringBuilder 
System.Data.OracleClient.OracleConnectionStringBuilder 
System.Data.SqlClient.SqlConnectionStringBuilder 

Por ejemplo, para "dar un vistazo a cabo el origen de datos" de una cadena de conexión de SQL-servidor, que puede hacer:

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

Utilice SqlConnectionStringBuilder Desafortunadamente, tendrá que usar un ConnectionStringBuilder específico de DB ya que las cadenas de conexión diffe r.

4

Sí, puede hacerlo utilizando clases ConnectionStringBuilder. Aquí está la lista de las implementaciones DbConnectionStringBuilder disponibles para los proveedores de datos estándar:

System.Data.Odbc.OdbcConnectionStringBuilder 
System.Data.OleDb.OleDbConnectionStringBuilder 
System.Data.OracleClient.OracleConnectionStringBuilder 
System.Data.SqlClient.SqlConnectionStringBuilder 

aquí son ejemplo de muestra de la cadena de conexión analizar y mostrar que es elementos.

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

Hay específicos del proveedor constructores de cadena de conexión de diversos proveedores como SqlConnectionStringBuilder, MySqlConnectionStringBuilder, SQLiteConnectionStringBuilder etc (por desgracia no hay ninguna interfaz pública de la MS en esta ocasión). De lo contrario, tiene DbProviderFactory.CreateConnectionStringBuilder que le dará una forma alternativa de escribirlo de manera independiente del proveedor. Debería especificar el proveedor en el archivo de configuración y tener la versión correcta de dll disponible. Por ejemplo,

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

Una vez escribí un análisis manual para mí que no me dio ningún problema. Sería trivial extender esto para dar información sobre otros parámetros (ahora mismo es solo para cosas simples como nombre de db, fuente de datos, nombre de usuario y contraseña). Más o menos así:

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

Para esto no necesita nada especial en el archivo de configuración, o cualquier dll en absoluto. Contains en Where cláusula es importante solo si necesita eludir cadenas de conexiones mal formateadas como server = localhost;pp; donde pp se agrega a nada.A comportarse como constructores normales (que estallaría en estos casos) cambiar las Where a

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

@Icarus no realmente ya que el comparador clave del diccionario es 'StringComparer.InvariantCultureIgnoreCase'. Ver la sobrecarga 'ToDictionary' – nawfal

+1

Sí, tienes razón, acabo de escribir una prueba rápida. Eliminaré mi comentario original ya que está mal. – Icarus

+2

Su método GetValue() no funcionará en casos donde, por ejemplo, el usuario tiene un '';'' o un ''='' en su contraseña. Escribí una implementación similar y aprendí que no funciona de la manera difícil. ¡Dios mío, el análisis de cadenas de conexión es en realidad mucho más difícil de lo que pensaba! –

11

está aquí un par de líneas de código que quisiera procesar a cualquier cadena de conexión en un diccionario:

Dictionary<string, string> connStringParts = connString.Split(';') 
    .Select(t => t.Split(new char[] { '=' }, 2)) 
    .ToDictionary(t => t[0].Trim(), t => t[1].Trim(), StringComparer.InvariantCultureIgnoreCase); 

Y entonces puede acceder a cualquier parte:

string dataSource = connStringParts["Data Source"]; 
+2

Inteligente, lo único que cambiaría sería incluir 'StringSplitOptions.RemoveEmptyEntries' a la primera división, ya que provocará una excepción' IndexOutOfRange' si hay un '; ' –

+2

final Esto funciona, pero los constructores de la cadena de conexión son más robustos . Un código como este arrojará excepciones de bajo nivel en lugar de errores de análisis más significativos en el caso de cadenas de conexión no válidas. – Sam

+0

Esto me ayudó a analizar una cadena de conexión ADO para poder construir una 'SqlConnection' equivalente con' SqlConnectionStringBuilder'. –

2

puede utilizar DbConnectionStringBuilder, y no necesita ningún proveedor específico:

El siguiente código:

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

salidas a la consola:

Data Source: data source value 
Server: ServerValue 

EDIT:

Desde DbConnectionStringBuilder implementa IDictionary se puede enumerar los parámetros de cadena de conexión:

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

Esto supone que ya sabe que la cadena de conexión tiene un valor de "Fuente de datos", etc., que no siempre es cierto, como se indica en http://stackoverflow.com/a/15529085/534109, más arriba. –

+0

Mi respuesta especifica específicamente lo que debe preguntar: 'Quiero poder ver, por ejemplo, "Fuente de datos' ' –

+0

Lo he editado para mostrar todos los parámetros de la cadena de conexión. –

0

Entonces encontré todo lo existente las respuestas fueron más o menos incorrectas. Terminé con la siguiente solución trivial:

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

El analizador está en DbConnectionStringBuilder y más o menos fácil de conseguir en. Lo único tonto que tenemos que hacer es configurar ShouldSerialize para que siempre devuelva verdadero para evitar la pérdida de componentes cuando intentemos el viaje de ida y vuelta en las cadenas de conexión arbitrarias.

+1

¿Qué pasaba con las respuestas existentes? O qué soluciona tu solución. La explicación sería útil. – nawfal

Cuestiones relacionadas