標籤:style blog color 使用 io 資料 for 問題
ADO.NET中 有了DbConnection,就可用DbConnection的CreateCommand 建立DbCommand,BeginTransaction建立DbTransaction
可以十分方便的實現原廠模式,操作不同的資料庫。
但是唯獨DbDataAdapter這個重要的對象無法通過DbConnection或DbCommand來建立,也無法執行個體化,必須使用SqlDataReader這種明確的類來建立執行個體,導致 擷取資料 的方法不能在基類實現
以下是兩個解決辦法:
1。只有我們自己靈活一點,手動判斷DbConnection的類型,並返回相應的DbDataAdapter,雖然比較笨,但是勉強能達到簡化繼承類的目的,代碼如下:
private DbDataAdapter CreateDataAdapter() { if (conPrivate is System.Data.SqlClient.SqlConnection) return new System.Data.SqlClient.SqlDataAdapter(); if (conPrivate is Sybase.Data.AseClient.AseConnection) return new Sybase.Data.AseClient.AseDataAdapter(); if (conPrivate is MySql.Data.MySqlClient.MySqlConnection) return new MySql.Data.MySqlClient.MySqlDataAdapter(); throw new NotImplementedException(); }
其中 conPrivate 是 DbConnection
2。換一個角度,發現DataTable有個Load方法可以使用IDataReader來擷取資料,而IDataReader可以使用DbCommand建立,不會出現DbDataAdapter無法執行個體化的問題。這樣便可在基類實現擷取資料的方法。
需要注意的是,直接使用DataTable.Load(IDataReader dr)來擷取資料的話,會帶上各種限制(不可為空,自增列,唯讀列等),在代碼中會很不方便。
不過我們知道,Fill方法內部,也是通過DbDataReader來實現填充資料的,為何同樣是用DbDataReader,Fill方法出來的DataTable就沒有任何限制呢?
使用Reflector對Fill方法進行查看,發現使用以下代碼即可,既能在基類中就實現擷取資料的方法,並且不會帶上Constraints
IDbCommand com = conPrivate.CreateCommand(); IDataReader dr = com.ExecuteReader(); DataSet ds = new DataSet(); DataTable dt = new DataTable(); ds.Tables.Add(dt); ds.Load(dr, LoadOption.OverwriteChanges, dt); ds.EnforceConstraints = false; return dt;