在使用數據庫通用類 DBHelper 操做 MySql 獲取 DataTable 時,DataTable 恆爲 nullhtml
先看看 DBHelper 獲取 DataTable 的代碼。mysql
public DataSet ExecuteDataSet(DbCommand cmd) { var dbfactory = DbProviderFactories.GetFactory(DbProviderName); var dbDataAdapter = dbfactory.CreateDataAdapter(); if (dbDataAdapter == null) return null; dbDataAdapter.SelectCommand = cmd; var ds = new DataSet(); dbDataAdapter.Fill(ds); return ds; }
源碼中使用了 Factory.CreateDataAdapter()
獲取 DbDataAdapter,再由 DbDataAdapter 將數據填充到 DataTable,並返回 DataTable。sql
跟蹤 DbFactory 和 DbDataAdapter,發現 DbDataAdapter 爲 null。數據庫
var factory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient"); var da = factory.CreateDataAdapter(); var f_mysql = MySqlClientFactory.Instance; var da_mysql = f_mysql.CreateDataAdapter();
額,DbDataAdapter 爲 null ?騙人的吧,既然爲 null,CreateDataAdapter()
還有啥用?oracle
對比下 CreateDataAdapter()
分別在 Oracle 和 Sqlite 中的狀況。ide
var factory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient"); var da = factory.CreateDataAdapter(); var f_mysql = MySqlClientFactory.Instance; var f_mssql = SqlClientFactory.Instance; var f_sqlite = SQLiteFactory.Instance; var f_oracle = OracleClientFactory.Instance; var da_mysql = f_mysql.CreateDataAdapter(); var da_mssql = f_mssql.CreateDataAdapter(); var da_sqlite = f_sqlite.CreateDataAdapter(); var da_oracle = f_oracle.CreateDataAdapter();
看看反編譯代碼,惟獨MySQLClientFactory沒實現 CreateDataAdapter() 方法code
<p style="text-decoration: underline;">MySqlDataAdapter>MySqlDataAdapter 不能由 MySqlClientFactory.CreateDataAdapter() 實例化。</p> 其實只是 config 文件沒配置好……sqlite
public DataSet ExecuteDataSet(DbCommand cmd) { var dbfactory = DbProviderFactories.GetFactory(DbProviderName); var dbDataAdapter = dbfactory.CreateDataAdapter(); if (dbDataAdapter == null) { if ("MySql.Data.MySqlClient" == DbProviderName) { dbDataAdapter = (DbDataAdapter) Assembly.Load("MySql.Data") .CreateInstance("MySql.Data.MySqlClient.MySqlDataAdapter"); } else { return null; } } if (dbDataAdapter == null) return null; dbDataAdapter.SelectCommand = cmd; var ds = new DataSet(); dbDataAdapter.Fill(ds); return ds; }