【问题标题】:Using SqlConnectionStringBuilder for EF connection string throws exception对 EF 连接字符串使用 SqlConnectionStringBuilder 会引发异常
【发布时间】:2017-05-15 12:33:07
【问题描述】:

我有这个小方法,它应该创建一个名为 DataSource 的自定义对象:

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

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

    return dbConnection;
}

我使用这个类 (SqlConnectionStringBuilder) 的主要原因是为了方便地抓取目录和数据源。

当我将实体框架连接字符串传递给它(并初始化SqlConnectionStringBuilder)时,我得到以下异常:

不支持关键字:“元数据”

我可以开始分析字符串以检查和区分实体框架连接字符串和经典连接字符串,但我真的想要一些优雅的东西来解决它们,而无需代码“知道”它(因为我在我的项目)。

这是失败的连接字符串示例:

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

此错误不会发生在经典连接字符串中,例如:

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

关于获取两种连接字符串的优雅的建议?除了SqlConnectionStringBuilder 之外,我还有什么可以使用的吗?也许我应该在尝试构建之前截断一些冗余字符串并将其从实体框架连接字符串中剥离出来?

提前致谢。

【问题讨论】:

标签: c# .net entity-framework connection-string


【解决方案1】:

我一直在使用自己创建的这个方法。也许这不是最优雅的解决方案,但它确实有效:

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

你可以使用这个过滤的connectionString来创建一个SqlConnectionStringBuilder,或者修改这个方法来提取数据源和初始目录。

【讨论】:

    【解决方案2】:

    我最终结合使用了这里提供的两种解决方案。 marc_s 建议使用 EntityConnectionStringBuilder 类,Alenjandro 建议检查提供程序以确定它是否为 EF 。 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;
        }
    

    在 EntityConnectionStringBuilder 中,我找到了 ProviderConnectionString 属性,这正是 SqlConnectionStringBuilder 类所期望的作为要解析的有效连接字符串值,因此除了额外的 if(我讨厌)之外,代码的行为几乎相同。

    感谢您的回答!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 2013-06-04
      相关资源
      最近更新 更多