2009-06-25 30 views
10

Làm thế nào để bạn xây dựng một DbConnection dựa trên một tên nhà cung cấp ?ASP.NET: Làm thế nào để tạo một kết nối từ web.config ConnectionString?

mẫu tên nhà cung cấp s

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

tôi có chuỗi kết nối được lưu trữ trong tệp web.config của máy chủ IIS của tôi:

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

Bạn có thể thấy tất cả họ đều sử dụng các nhà cung cấp khác nhau. Khi nói đến thời gian cho tôi để tạo ra một kết nối, tôi phải biết những loại DbConnection để tạo ra, ví dụ:

  • SqlConnection
  • OleDbConnection
  • OdbcConnection
  • FbConnection

Các mục nhập connectionStrings chứa một nhà cung cấp Name, nhưng đây không phải là tên của các lớp hậu duệ DbConnection, nhưng có vẻ như là một không gian tên

Làm cách nào để tôi biến cấu trúc DbConnection dựa trên chuỗi providerName?


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(); 

} 

Trả lời

15

Nếu bạn đi tuyến đường này, tôi nghĩ bạn sẽ muốn sử dụng lớp DbProviderFactories để có được một DbProviderFactory mà bạn có thể sử dụng để xây dựng kết nối. Tôi đã không thử mã này, nhưng tôi nghĩ nó sẽ hoạt động. Có thể bạn cần tra cứu tên nhà cung cấp bằng phương thức GetFactoryClasses trên lớp DbProviderFactories và sử dụng 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; 
} 
+1

Đây chính xác là những gì cần thiết. Thành phần bí mật là "tên nhà cung cấp" được sử dụng ở đâu đó trong hệ thống, và đó là bộ sưu tập DbProviderFactories. Mỗi nhà cung cấp đăng ký chính nó với DbProviderFactories; đó là cách bạn tìm thấy nó. –

0

Check-out this Hanselman blog về việc bổ sung tùy chỉnh xây dựng các loại cho tên chuỗi kết nối khác nhau, có vẻ như nó có thể phù hợp với những gì bạn muốn đạt được theo một cách khác hơn là sử dụng các loại nhà cung cấp.

+0

Nó không phải là các bản dựng khác nhau. Một hệ thống phải kết nối với nhiều cơ sở dữ liệu khác nhau dựa trên hoàn cảnh. –

+1

ahh, tôi hiểu nhầm ví dụ. Tôi sẽ không nghĩ rằng một ứng dụng sẽ kết nối với phát triển, sản xuất và thử nghiệm cùng một lúc. – blu

0

Nếu nhà cung cấp tên cho tên kết nối cụ thể (dev, test, prod) không bao giờ thay đổi tại sao bạn không thể chuyển đổi tên kết nối param cho phương thức của bạn và đặt cá thể providerName theo cách đó?

+0

Vì đó không phải là câu hỏi này. –

+0

Bởi vì cách đó nằm điên rồ. Năm năm sau, một dev mới được giao nhiệm vụ di chuyển cơ sở dữ liệu thử nghiệm từ SQL Server sang Oracle. Họ cập nhật chuỗi kết nối và không thành công. Các giả định ẩn như thế này (tức là cơ sở dữ liệu dev sử dụng nhà cung cấp cơ sở dữ liệu X) là một cách rất tốt để gây ra những giọt nước mắt trên đường. – Yuliy

+0

Thành thật mà nói, nó không phải là một giải pháp tốt để bắt đầu. Để mã sản xuất của bạn phụ thuộc vào các nhà cung cấp DB thay đổi động, hãy mang nước mắt lâu trước khi cố gắng giải quyết câu hỏi này tại đây. – Marc

Các vấn đề liên quan