情景
在使用数据库通用类 DBHelper 操作 MySql 获取 DataTable 时,DataTable 恒为 null
过程
先看看 DBHelper 获取 DataTable 的代码。
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。
跟踪 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()
还有啥用?
对比下 CreateDataAdapter()
分别在 Oracle 和 Sqlite 中的情况。
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() 方法
结论
<p style="text-decoration: underline;">MySqlDataAdapter>MySqlDataAdapter 不能由 MySqlClientFactory.CreateDataAdapter() 实例化。</p> 其实只是 config 文件没配置好……
其他
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;}