J'ai une chaîne de connexion et je veux pouvoir voir par exemple "Source de données". Existe-t-il un analyseur ou dois-je rechercher la chaîne?
J'ai une chaîne de connexion et je veux pouvoir voir par exemple "Source de données". Existe-t-il un analyseur ou dois-je rechercher la chaîne?
Réponses:
Oui, il y a la System.Data.Common.DbConnectionStringBuilder
classe.
La classe DbConnectionStringBuilder fournit la classe de base à partir de laquelle dérivent les générateurs de chaînes de connexion fortement typées (SqlConnectionStringBuilder, OleDbConnectionStringBuilder, etc.). Les générateurs de chaînes de connexion permettent aux développeurs de créer par programme des chaînes de connexion syntaxiquement correctes, et d'analyser et de reconstruire les chaînes de connexion existantes.
Les sous-classes d'intérêt sont:
System.Data.EntityClient.EntityConnectionStringBuilder
System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.OracleClient.OracleConnectionStringBuilder
System.Data.SqlClient.SqlConnectionStringBuilder
Par exemple, pour "jeter un œil à la source de données" à partir d'une chaîne de connexion SQL-server, vous pouvez faire:
var builder = new SqlConnectionStringBuilder(connectionString);
var dataSource = builder.DataSource;
Il y a des constructeurs de chaîne de connexion spécifique des fournisseurs de divers fournisseurs tels que SqlConnectionStringBuilder
, MySqlConnectionStringBuilder
, SQLiteConnectionStringBuilder
etc (malheureusement il n'y a pas d' interface publique de MS cette fois -ci ). Sinon, vous avez DbProviderFactory.CreateConnectionStringBuilder qui vous donnera une autre façon de l'écrire de manière indépendante du fournisseur. Vous devrez spécifier le fournisseur dans le fichier de configuration et disposer de la bonne version de la dll. Par exemple.,
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"];
J'avais une fois écrit une analyse manuelle pour moi-même, ce qui ne me posait aucun problème. Il serait trivial d'étendre cela pour donner des informations sur d'autres paramètres (pour le moment, ce n'est que pour des choses simples comme le nom de la base de données, la source de données, le nom d'utilisateur et le mot de passe). Comme ceci ou deux:
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;
}
Pour cela, vous n'avez besoin de rien de spécial dans le fichier de configuration, ni d'aucune dll. Contains
La Where
clause in n'est importante que si vous avez besoin de contourner les chaînes de connexion mal formatées comme server = localhost;pp;
où pp
n'ajoute rien. Pour se comporter comme les constructeurs normaux (qui exploserait dans ces cas) changer Where
à
.Where(kvp => !string.IsNullOrWhitespace(kvp))
StringComparer.InvariantCultureIgnoreCase
. Voir la ToDictionary
surcharge
';'
ou un '='
dans son mot de passe. J'avais écrit une implémentation similaire et appris qu'elle ne fonctionnait pas à la dure. Gosh, l'analyse des chaînes de connexion est en fait beaucoup plus difficile que je ne le pensais!
Voici quelques lignes de code qui analysent n'importe quelle chaîne de connexion dans un dictionnaire:
Dictionary<string, string> connStringParts = connString.Split(';')
.Select(t => t.Split(new char[] { '=' }, 2))
.ToDictionary(t => t[0].Trim(), t => t[1].Trim(), StringComparer.InvariantCultureIgnoreCase);
Et puis vous pouvez accéder à n'importe quelle partie:
string dataSource = connStringParts["Data Source"];
StringSplitOptions.RemoveEmptyEntries
la première division, car cela causera une IndexOutOfRange
exception s'il y a un suivi;
SqlConnection
avec le SqlConnectionStringBuilder
.
Utilisez le SqlConnectionStringBuilder Malheureusement, vous devrez utiliser un ConnectionStringBuilder spécifique à la base de données car les chaînes de connexion diffèrent.
Vous souhaitez utiliser DbProviderFactory.CreateConnectionStringBuilder () qui vous fournit un générateur / analyseur de chaîne de connexion spécifique à votre connecteur, mais ne vous oblige pas à utiliser des classes spécifiques au connecteur.
Oui, vous pouvez le faire à l'aide des classes ConnectionStringBuilder. Voici la liste des implémentations DbConnectionStringBuilder disponibles pour les fournisseurs de données standard:
System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.OracleClient.OracleConnectionStringBuilder
System.Data.SqlClient.SqlConnectionStringBuilder
Voici un exemple d'exemple d'analyse de la chaîne de connexion et d'afficher ses éléments.
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);
Vous pouvez utiliser DbConnectionStringBuilder et vous n'avez besoin d'aucun fournisseur spécifique:
Le code suivant:
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"]);
Sorties vers la console:
Data Source: data source value
Server: ServerValue
ÉDITER:
Puisque DbConnectionStringBuilder implémente IDictionary, vous pouvez énumérer les paramètres de la chaîne de connexion:
foreach (KeyValuePair<string, object> kv in builder)
{
Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
}
Je n'ai pas vraiment aimé toutes les réponses ici. Voici donc ce que j'ai trouvé.
Vous pouvez utiliser DbConnectionStringBuilder
directement:
var builder = new System.Data.Common.DbConnectionStringBuilder();
builder.ConnectionString = settings.ConnectionString;
var server = builder["server"];
J'ai donc trouvé que toutes les réponses existantes étaient plus ou moins fausses. J'ai fini avec la solution triviale suivante:
class ConnectionStringParser: DbConnectionStringBuilder {
ConnectionStringParser(string c) { Connection = c; }
public override bool ShouldSerialize(string keyword) => true;
}
L'analyseur est dans DbConnectionStringBuilder et assez facile d'accès. La seule chose idiote que nous devons faire est de définir ShouldSerialize pour toujours retourner true pour éviter de perdre des composants lorsque vous essayez d'aller-retour des chaînes de connexion arbitraires.
DbConnectionStringBuilder
a des fonctionnalités de traitement génériques qui peuvent être utilisées sans utiliser de sous-classes:if (builder.TryGetValue("Password", out var pwd)) { string decrypted = SomehowDecrypt(pwd); builder["Password"] = decrypted; }