2017-05-15 4 views
4

J'ai cette petite méthode qui devrait créer un objet personnalisé appelé DataSource:En utilisant SqlConnectionStringBuilder pour chaîne de connexion EF throws Exception

private static DataSource BuildDataSourceFromString(string connectionString) 
{ 
    SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); 

    DataSource dbConnection = new DataSource() 
     { 
      Source = builder.DataSource, 
      Catalog = builder.InitialCatalog 
     }; 

    return dbConnection; 
} 

La principale raison pour laquelle j'utilise cette classe (SqlConnectionStringBuilder) est de saisir confortablement le catalogue et les données la source.

Quand je passe une chaîne de connexion Entity Framework pour (et initialiser le SqlConnectionStringBuilder), je reçois l'exception suivante:

mots-clés non pris en charge: 'métadonnées'

Je pourrais commencer à analyser la chaîne à vérifier et à différencier entre la chaîne de connexion Entity Framework et la chaîne classique, mais je veux vraiment quelque chose d'élégant pour les traiter sans que le code doive en "savoir" (car j'en réitère plusieurs types dans mon projet).

Voici l'exemple de chaîne de connexion qui échoue:

<add name="someconnectionstring" 
    connectionString="metadata=res://*/DB.SomeDataModel.csdl|res://*/DB.SomeDataModel.ssdl|res://*/DB.SomeDataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=some-data-source;initial catalog=SomeCatalog;integrated security=True;MultipleActiveResultSets=True;MultiSubnetFailover=True;App=EntityFramework&quot;" 
    providerName="System.Data.EntityClient" /> 

Cette erreur ne se produit pas dans les chaînes de connexion classiques comme:

<connectionStrings> 
    <add name="SomeData" 
     connectionString="Server=Some-Server;Database=SomeCatalog;Integrated Security=SSPI;" 
     providerName="System.Data.sqlclient" /> 
</connectionStrings> 

Suggestions pour quelque chose d'élégant pour saisir les deux types de chaînes de connexion? Y at-il autre chose que SqlConnectionStringBuilder que je peux utiliser? Peut-être que je devrais tronquer une chaîne redondante et la retirer de la chaîne de connexion Entity Framework avant de la construire?

Merci d'avance.

+1

Avez-vous essayé la classe 'EntityConnectionStringBuilder'? https://msdn.microsoft.com/en-us/library/system.data.entityclient.entityconnectionstringbuilder(v=vs.110).aspx –

Répondre

1

J'ai utilisé cette méthode créée par moi-même. Peut-être que ce n'est pas la solution la plus élégante, mais cela fonctionne:

private static string FilterConnectionString(string connectionStringEntity, bool useProvider = true) 
     { 
      string result = ""; 
      string[] split = connectionStringEntity.Split(new char[2] { ';', '"' }, StringSplitOptions.RemoveEmptyEntries); 
      foreach (var item1 in split) 
      { 
       string item = item1.Trim(); 
       if (item.ToLower().StartsWith("data source") || 
        item.ToLower().StartsWith("initial catalog") || 
        item.ToLower().StartsWith("user id") || 
        item.ToLower().StartsWith("password") || 
        item.ToLower().StartsWith("multipleactiveresultSets")) 
        result += item + ";"; 
      } 
      return useProvider ? result + "provider=System.Data.SqlClient" : result; 
     } 

Vous pouvez utiliser cette connectionString filtrée pour créer un SqlConnectionStringBuilder, ou de modifier cette méthode pour extraire la source de données et le catalogue initial.

0

J'ai finalement utilisé les deux solutions proposées ici combinées. marc_s a suggéré d'utiliser la classe EntityConnectionStringBuilder et Alenjandro a suggéré de vérifier le fournisseur pour déterminer s'il s'agit de EF. EntityConnectionStringBuilder ne peut pas analyser System.Data.SqlClient régulière afin:

 ... 
     XAttribute provider = connectionStringElement.Attribute("providerName"); 
     string providerValue = provider == null ? string.Empty : provider.Value; 

     bool isEntityFramework = providerValue.Equals("System.Data.EntityClient"); 
     dbConn = BuildDataSourceFromString(connectionStringValue, isEntityFramework); 
     if (dbConn == null) 
     { 
      return; 
     } 

     connectionStrings.Add(dbConn); 
    } 
    private static DataSource BuildDataSourceFromString(string connectionString, bool isEntityFramework) 
    { 
     log.InfoFormat("Is connection string entity framework ? {0}", isEntityFramework.ToString()); 
     if (isEntityFramework) 
     { 
      EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder(connectionString); 
      connectionString = entityBuilder.ProviderConnectionString; 
     } 

     SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); 


     DataSource dbConnection = new DataSource() 
     { 
      Source = builder.DataSource, 
      Catalog = builder.InitialCatalog 
     }; 
     return dbConnection; 
    } 

Dans le EntityConnectionStringBuilder j'ai trouvé le ProviderConnectionString de propriété qui est exactement ce que vous attendez la classe SqlConnectionStringBuilder comme une valeur de chaîne de connexion valide pour analyser, donc en plus que if supplémentaire (ce que je déteste) le code se comporte presque pareil.

Merci pour les réponses!