2010-09-05 67 views
12

我發現這段代碼在一個應用程序C#的DbConnection投來的SqlConnection

Database database = DatabaseFactory.CreateDatabase("connection string"); 
DbConnection connection = database.CreateConnection(); 
connection.Open(); 
SqlConnection sqlConnection = (SqlConnection)connection; 

它是安全的,SqlConnection的距離的DbConnection derieve。數據庫來自Microsoft.Practices.EnterpriseLibrary.Data。根據文檔CreteDatabase返回DbConnection。

回答

11

不,它是不是安全,鑄造不安全,如果您的應用程序運行時,可能隨時打擊。雖然SqlConnection的確從DbConnection派生,但不能保證database.CreateConnection()將返回SqlConnection,因爲這可以在配置文件中進行參數化。另外你爲什麼需要投到SqlConnection?處理層次結構中較高級的類總是更好,以避免將代碼與特定的實現耦合,這將使您的代碼無法獨立測試。

儘管EnterpriseLibrary在保持抽象的功能方面做得非常好,但您仍然在使用這個Cast來殺死所有的東西。你也應該確保一次性資源總是妥善處理。如何改爲:

Database database = DatabaseFactory.CreateDatabase("connection string"); 
using (var conn = database.CreateConnection()) 
using (var cmd = conn.CreateCommand()) 
{ 
    conn.Open(); 
    cmd.CommandText = "SELECT id FROM foo"; 
    using (var reader = cmd.ExecuteReader()) 
    { 
     while (reader.Read()) 
     { 
      // TODO: work with the results here 
     } 
    } 
} 

這樣你的代碼對配置文件中數據庫更改的脆弱程度就會降低。當然,你仍然有這個SQL硬編碼,並有ORMs將照顧這種情況。他們還將允許您專注於應用程序的真實領域,而不是浪費時間編寫SQL查詢並從一個數據庫提供者投射到另一個數據庫提供者。但對於一個簡單的應用程序來說,這沒問題

+0

此代碼中使用的方法需要SqlConnection作爲參數 – Darqer 2010-09-05 23:52:10

7

只要您不更改連接字符串以連接到SQL Server數據庫以外的任何其他應用程序,它應該是安全的。如果這是永遠的可能性,那麼你應該多添一點邏輯,使事情安全:

Database database = DatabaseFactory.CreateDatabase("conn string"); 

using(DbConnection conn = database.CreateConnection()) 
{  
    if(conn is SqlConnection) 
    { 
     var sqlConn = conn as SqlConnection; 
    } 
} 
+0

沒有太大的區別,使用'as'without'is',然後檢查null是更有效的。 – 2012-02-14 23:44:23

4

這取決於您在應用程序中使用的數據庫。從您編寫的代碼看起來像只使用SQL Server。如果是這樣,那麼你可以安全地投下DbConnectionSqlConnection。實際上DbConnection是任何其他數據庫連接的基類。在你的情況下,它是SqlConnection(它與SQL Server數據庫一起使用),也有不同的數據庫,如Oracle,Mysql等,他們的提供者通常有自己的連接類。因此,如果您的應用程序使用其他數據庫或將來可能使用,則進行此類轉換是不安全的。

+2

它不僅取決於使用的數據庫,而且更直接地取決於工廠根據使用的數據庫返回的類型。如果他們決定創建一個使用SQL Server的新連接類,代碼可能會失敗 – 2010-09-05 20:09:23