首页 > 代码库 > 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;