简体   繁体   English

将SqlConnectionStringBuilder用于EF连接字符串会引发异常

[英]Using SqlConnectionStringBuilder for EF connection string throws exception

I have this small method which should create a custom object called DataSource : 我有这个小的方法,应该创建一个名为DataSource的自定义对象:

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

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

    return dbConnection;
}

The main reason I use this class ( SqlConnectionStringBuilder ) is to comfortably grab the catalog and data source. 我使用此类( SqlConnectionStringBuilder )的主要原因是可以轻松地获取目录和数据源。

When I pass an Entity Framework connection string to it (and initialize the SqlConnectionStringBuilder ), I get the following exception: 当我向其传递Entity Framework连接字符串(并初始化SqlConnectionStringBuilder )时,出现以下异常:

Keyword not supported: 'metadata' 不支持的关键字:“元数据”

I could start analyzing the string to check and differentiate between Entity Framework connection string and classic one, but really want something elegant to address them both without the code having to "know" about it (because I iterate many kinds of them in my project). 我可以开始分析该字符串以检查并区分Entity Framework连接字符串和经典字符串,但确实想要一种优雅的方法来解决这两个问题,而无需代码“了解”(因为我在项目中迭代了许多类型) 。

Here is the connection string example which fails: 这是失败的连接字符串示例:

<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" />

This error does not happen in classic connection strings like : 在经典的连接字符串中不会发生此错误:

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

Suggestions for something elegant to grab both kinds of connection strings? 建议使用一些优雅的方法来抓住这两种连接字符串? Is there something else except SqlConnectionStringBuilder that I can use? 除了SqlConnectionStringBuilder之外,还有其他可以使用的东西吗? Maybe I should truncate some redundant string and strip it away from the Entity Framework connection string before I try to build it? 也许我应该截断一些多余的字符串并将其从Entity Framework连接字符串中剥离,然后再尝试构建它?

Thanks in advance . 提前致谢 。

I have been using this method created by myself. 我一直在使用自己创建的这种方法。 Maybe it's not the most elegant solution, but it works: 也许这不是最优雅的解决方案,但它可行:

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

You can use this filtered connectionString to create a SqlConnectionStringBuilder, or modify this method to extract the datasource and initial catalog. 您可以使用此筛选后的connectionString创建SqlConnectionStringBuilder,或修改此方法以提取数据源和初始目录。

I eventually used both of the offered solutions here combined . 我最终将这里提供的两种解决方案结合使用。 marc_s suggested using the class EntityConnectionStringBuilder and Alenjandro suggested checking the provider to determine if it's EF . marc_s建议使用EntityConnectionStringBuilder类,而Alenjandro建议检查提供程序以确定它是否为EF。 EntityConnectionStringBuilder cannot parse regular System.Data.SqlClient so : EntityConnectionStringBuilder无法解析常规System.Data.SqlClient,因此:

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

In the EntityConnectionStringBuilder i found the property ProviderConnectionString which is exactly what the SqlConnectionStringBuilder class expect as a valid connection string value to parse , so besides that extra if (which i hate) the code behaves almost the same . 在EntityConnectionStringBuilder我找到了物业ProviderConnectionString这也正是SqlConnectionStringBuilder类预期为有效的连接字符串的值来解析,因此,除了额外的if (我恨)代码的行为几乎是相同的。

Thanks for the answers ! 感谢您的回答!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM