【问题标题】:ASP.NET: How to create a connection from a web.config ConnectionString?ASP.NET:如何从 web.config ConnectionString 创建连接?
【发布时间】:2010-11-05 23:20:22
【问题描述】:

如何根据提供者名称构建 DbConnection?

示例提供者名称s

  • System.Data.SqlClient
  • System.Data.OleDb
  • System.Data.Odbc
  • FirebirdSql.Data.FirebirdClient

我的 IIS 服务器的 web.config 文件中存储了连接字符串:

<connectionStrings>
  <add name="development"
        connectionString="Provider = IBMDA400; Data Source = MY_SYSTEM_NAME; User Id = myUsername; Password = myPassword;" 
        providerName="System.Data.OleDb" />
  <add name="live" 
        connectionString="usd=sa;pwd=password;server=deathstar;" 
        providerName="System.Data.Odbc" />
  <add name="testing" 
        connectionString="usd=sa;pwd=password;server=deathstar;" 
        providerName="System.Data.SqlClient" />
  <add name="offline"
        connectionString="Server=localhost;User=SYSDBA;Password=masterkey;Charser=NONE;Database=c:\data\mydb.fdb"
        providerName="FirebirdSql.Data.FirebirdClient"/>

您可以看到他们都使用不同的提供程序。当我需要创建连接时,我必须知道要创建什么样的 DbConnection,例如:

  • SqlConnection
  • OleDbConnection
  • OdbcConnection
  • Facebook 连接

connectionStrings 条目包含一个 providerName,但这些不是 DbConnection 后代类的名称,而是一个 命名空间

如何根据字符串 providerName 构建 DbConnection?


public DbConnection GetConnection(String connectionName)
{
    //Get the connectionString infomation
    ConnectionStringSettings cs = 
          ConfigurationManager.ConnectionStrings[connectionName];
    if (cs == null)
       throw new ConfigurationException("Invalid connection name \""+connectionName+"\");

    //Create a connection based on the provider
    DbConnection conn = new DbConnection();

}

【问题讨论】:

    标签: ado.net web-config provider connection-string dbconnection


    【解决方案1】:

    如果你走这条路,我想你会想要使用 DbProviderFactories 类来获得一个 DbProviderFactory,你可以用它来构造连接。我还没有尝试过这段代码,但我认为它会起作用。您可能需要使用 DbProviderFactories 类上的 GetFactoryClasses 方法查找提供程序名称并使用 InvariantName。

    public DbConnection GetConnection(String connectionName)
    {
       //Get the connection string info from web.config
       ConnectionStringSettings cs= 
             ConfigurationManager.ConnectionStrings[connectionName];
    
       //documented to return null if it couldn't be found
       if (cs == null)
          throw new ConfigurationErrorsException("Invalid connection name \""+connectionName+"\"");
    
       //Get the factory for the given provider (e.g. "System.Data.SqlClient")
       DbProviderFactory factory = 
             DbProviderFactories.GetFactory(cs.ProviderName);
    
       //Undefined behaviour if GetFactory couldn't find a provider.
       //Defensive test for null factory anyway
       if (factory == null)
          throw new Exception("Could not obtain factory for provider \""+cs.ProviderName+"\"");
    
       //Have the factory give us the right connection object      
       DbConnection conn = factory.CreateConnection();
    
       //Undefined behaviour if CreateConnection failed
       //Defensive test for null connection anyway
       if (conn == null)
          throw new Exception("Could not obtain connection from factory");
    
       //Knowing the connection string, open the connection
       conn.ConnectionString = cs.ConnectionString;
       conn.Open()
    
       return conn;
    }
    

    【讨论】:

    • 这正是我们所需要的。秘密成分是在系统某处使用的“提供者名称”,即集合 DbProviderFactories。每个提供者都向 DbProviderFactories 注册自己;这就是你找到它的方式。
    【解决方案2】:

    查看this Hanselman blog 为不同的连接字符串名称添加自定义构建类型,看起来它可能适合您想要以不同于使用提供程序类型的方式完成的任务。

    【讨论】:

    • 这不是不同的构建。一个系统必须根据情况连接到各种数据库。
    • 啊,我误解了这个例子。我认为应用程序不会同时连接到开发、生产和测试。
    【解决方案3】:

    如果特定连接名称(dev、test、prod)的 providerName 永远不会改变,为什么你不能为你的方法打开 connectionName 参数并以这种方式设置 providerName 实例?

    【讨论】:

    • 因为不是这个问题。
    • 因为那是疯狂的地方。五年后,一位新开发人员被分配了将测试数据库从 SQL Server 迁移到 Oracle 的任务。他们更新了连接字符串,但它失败了。像这样的隐藏假设(即 dev 数据库使用 X 数据库提供程序)是一种非常好的方法,可以让我们在路上流泪。
    • 老实说,这不是一个好的解决方案。让您的生产代码依赖于动态变化的数据库提供程序,早在尝试在这里解决这个问题之前就会让人流泪。
    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多