首页 > 代码库 > C# CreateDataAdapter 创建 DbDataAdapter,以及用DataTable的Load方法获取数据
C# CreateDataAdapter 创建 DbDataAdapter,以及用DataTable的Load方法获取数据
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;