欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

简化ADO.NET数据访问的类库(类似MS Data Access Application Bl

程序员文章站 2022-04-01 08:27:19
...

Execute 类 概述 Execute 类中实现了 IExecute 接口与 IExecuteEx 接口。对数据库进行简单操作时,通过 IExecute 接口调用 Execute 类中的功能;进行较复杂的操作时,需通过 IExecuteEx 接口调用 Execute 类中的功能。 实例化 Execute 类有 3 个重载的构造函

Execute

概述

Execute类中实现了IExecute接口与IExecuteEx接口。对数据库进行简单操作时,通过IExecute接口调用Execute类中的功能;进行较复杂的操作时,需通过IExecuteEx接口调用Execute类中的功能。

实例化

Execute类有3个重载的构造函数,分别为:

Execute(dbType:DatabaseType)

Execute(connectionString:string, sql:string, dbType:DatabaseType)

Execute(connectionString:string, sql:string, dbType:DatabaseType, showError:IShowError)

其中参数意义如下:

dbType: 数据库类型,枚举类型DatabaseType的值之一;

connectionString: 连接字符串;

sql: SQL语句;

showError: 错误显示对象,为IShowError接口类型。

说明:

Execute类的实例化时,除了数据库类型必须指定之外,其它参数都可以在实例化以后,通过对相应的属性赋值进行指定或重新指定。

IExecute接口

概述

IExecute接口设计用来执行简单的数据库操作,通过它可以执行无返回的数据库操作如向数据库插入、更新、删除记录的操作,也可执行有返回数据库操作,返回的数据集放在DataSet对象中;它不支持执行存储过程,也不支持通过改变DataSet中的数据,间接地修改数据库;它对数据库的操作都是离线操作,即使用它的方法时自动完成连接-执行-断开的过程,因此它不支持DataReader式的在线数据库读取操作。

实例化

IExecute接口的实例化需通过Execute类的实例化完成。参看Execute类的实例化说明。

例如:

Tao.Data.DataExecute.IExecute execute=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

属性

IExecute接口有如下属性:

ConnectionString:string 只写属性,用来指定连接字符串

SQL:string 只写属性,用来指定SQL语句

CommandParameters:ITaoParameters 只读属性,用来给SQL语句中的参数赋值

ShowError:IShowError 只写属性,用来指定显示错误对象

属性的主要作用是指定数据库操作逻辑。

数据库操作逻辑的指定

在实例化时就可以指定数据库操作逻辑,也可以不在实例化时指定,而在实例化之后,通过对ConnectionString, SQL属性赋值进行指定。例如:

1. 在实例化之后对属性赋值指定参数

//准备参数

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

string sql="insert into person(name) values(@name)";

IShowError showerror=new Tao.Data.DataExecute.Windows.ShowWindowsError();

//实例化

Tao.Data.DataExecute.IExecute execute=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

//给属性赋值指定参数

execute.ConnectionString=constr;

execute.SQL=sql;

execute.ShowError=showerror;

2. 在实例化时指定所有参数

//实例化

Tao.Data.DataExecute.IExecute execute=new Tao.Data.DataExecute.Execute(constr, sql, Tao.Data.DataConfig.DatabaseType.OleDb, showerror);

使用带参数的SQL语句

当赋入的SQL语句带有参数时,需通过CommandParameters属性对参数赋值。例如:

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

string sql=" insert into person(name) values(@name)";

Tao.Data.DataExecute.IExecute execute=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

execute.ConnectionString=constr;

execute.SQL=sql;

execute.CommandParameters.Add("@name","aa")

if(execute.ExecuteNonQuery())MessageBox.Show("OK");

数据库操作逻辑的更新

当使用IExecute接口执行了数据库操作之后,可以无须重新实例化执行对象,只需为其指定新的数据库逻辑,如赋入新的连接字符串或SQL语句,执行对象将自动应用的数据库逻辑。例如:

//最初的数据库逻辑

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

string sql=" insert into person(name) values('aa')";

Tao.Data.DataExecute.IExecute execute=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

execute.ConnectionString=constr;

execute.SQL=sql;

if(execute.ExecuteNonQuery())MessageBox.Show("OK");

//改变数据操作逻辑

execute.SQL="delete from person where name='aa'";

if(execute.ExecuteNonQuery())MessageBox.Show("OK");

方法

IExecute接口有如下方法:

ExecuteNonQuery: bool 执行无返回的数据库操作

ExecuteDataSet: DataSet 2次重载,执行有返回的数据库操作,返回的数据集在DataSet对象中

ExecuteNonQuery方法

ExecuteNonQuery(): bool

参数:

无参数。

返回值:

bool类型,当操作成功时返回true,操作失败时返回false

依赖:

使用前须指定数据库操作逻辑。

说明:

用来执行无返回的数据库操作。例如:

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

string sql=" insert into person(name) values('aa')";

Tao.Data.DataExecute.IExecute execute=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

execute.ConnectionString=constr;

execute.SQL=sql;

if(execute.ExecuteNonQuery())MessageBox.Show("OK");

ExecuteDataSet方法

2次重载

ExecuteDataSet():DataSet

ExecuteDataSet(startRecord:int, maxRecords:int, srcTable:string) : DataSet

参数:

startRecord:int 从其开始的从零开始的记录号

maxRecords:int 要检索的最大记录数

srcTable:string 用于表映射的源表的名称

返回值:

DataSet类型,用来存放取得的数据集。

依赖:

使用前须指定数据库操作逻辑。

说明:

用来执行有返回的数据库操作。例如:

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

sql="select * from person";

Tao.Data.DataExecute.IExecute execute=new Tao.Data.DataExecute.Execute(constr,sql,Tao.Data.DataConfig.DatabaseType.OleDb);

DataSet ds=execute.ExecuteDataSet();

this.dataGrid1.DataSource=ds.Tables[0];

DataSet ds=execute.ExecuteDataSet(0,5,"person");

this.dataGrid1.DataSource=ds.Tables["person"];

IExecuteEx接口

概述

IExecuteEx接口设计用来执行较复杂的数据库操作。它的使用类似于.NET框架中基本数据库类的使用,即分别使用Command, DataAdapter, DataReader等对象。它可以执行无返回的数据库操作如向数据库插入、更新、删除记录的操作,也可执行有返回的数据库操作;它支持执行存储过程,也支持通过改变DataSet中的数据,间接地修改数据库,它还支持DataReader的在线数据库读取操作。

实例化

IExecuteEx接口的实例化需通过Execute类的实例化完成。参看Execute类的实例化说明。

例如:

Tao.Data.DataExecute.IExecuteEx execute=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

属性

IExecuteEx接口有如下属性:

ConnectionString:string 只写属性,用来指定连接字符串

SQL:string 只写属性,用来指定SQL语句

ShowError:IShowError 只写属性,用来指定显示错误对象

Command:ITaoCommand 只读属性,表示要对数据源执行的 SQL 语句或存储过程

CommandBuilder:ITaoCommandBuilder只读属性,自动生成用于协调DataSet的更改与关联数据库的单表命令

DataAdapter:ITaoDataAdapter 只读属性,表示一组数据命令和一个数据库连接,它们用于填充DataSet和更新数据源

DataReader:ITaoDataReader 只读属性,提供从数据源读取数据行的只进流的方法

以上属性可以分成两类,一类是指定数据库操作逻辑的属性,即ConnectionStringSQL;另一类是执行数据库操作的属性,即Command, CommandBuilder, DataAdapterDataReader

数据库操作逻辑的指定

通过ConnectionString, SQL属性指定数据库操作逻辑,参看IExecute接口的数据库操作逻辑的指定。

通过Command属性指定SQL语句,参看Command属性。

Command属性

只读属性。ITaoCommand类型。通过它可以指定SQL语句,使用带参数的SQL语句,使用存储过程,执行无返回的数据库操作和简单的有返回的数据库操作。

1. 指定SQL语句

例如:

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

sql="insert into person(name) values('aa')";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

executeex.ConnectionString=constr;

executeex.Command.CommandText=sql;

int n=executeex.Command.ExecuteNonQuery();

MessageBox.Show("changed lines is: "+n.ToString());

2. 使用带参数的SQL语句

例如:

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

sql="insert into person(name) values(@name)";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

executeex.ConnectionString=constr;

executeex.Command.CommandText=sql; //或使用executeex.SQL= sql;

executeex.Command.Parameters.Add("@name","aa");

int n=executeex.Command.ExecuteNonQuery();

MessageBox.Show("changed lines is: "+n.ToString());

3. 清除参数

ITaoParameters下有一个Clear方法,用来清除已赋给CommandParameters属性所有参数。

例如:

sql="select name from person where name=@name";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

executeex.ConnectionString=constr;

executeex.Command.CommandText=sql;

executeex.Command.Parameters.Add("@name","aaaa");

executeex.Command.Parameters.Clear();

executeex.Command.Parameters.Add("@name","bbbb");

string msg="";

while(executeex.DataReader.Read())

msg+=executeex.DataReader.GetString(0)+"/r/n";

executeex.DataReader.Close();

this.textBox1.Text=msg;

上面代码运行后,msg中的值为"bbbb",如果删去executeex.Command.Parameters.Clear();一句,运行结果则为"aaaa"

4. 使用存储过程

例如:

数据库中有此存储过程,

ALTER PROCEDURE sp_Orders_ByEmployeeId

(

@EmployeeID int

)

AS

SELECT OrderId,OrderDate

FROM Orders

WHERE EmployeeId=@EmployeeID

RETURN

代码如下,

using System.Data

//...

constr="Data Source=Shark;Integrated Security=true;database=Northwind";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.Sql);

executeex.ConnectionString=constr;

executeex.Command.CommandType=CommandType.StoredProcedure;

executeex.Command.CommandText="sp_Orders_ByEmployeeId"; //executeex.SQL="sp_Orders_ByEmployeeId";

executeex.Command.Parameters.Add("@EmployeeID",(int)SqlDbType.Int).Value=2;

DataSet ds=new DataSet();

executeex.DataAdapter.Fill(ds);

this.dataGrid1.DataSource=ds.Tables[0];

executeex.Command.CommandType=CommandType.Text;//恢复为默认值

5. 使用CommandBehavior属性

System.Data中的CommandBehavior枚举,提供对查询结果和查询对数据库的影响的说明。这个枚举值被用于IDbCommand.ExecuteReader 方法的参数。在这里被设计成ITaoCommand接口的属性。具体使用参看DataReader属性。

CommandBuilder属性

只读属性。ITaoCommandBuilder类型。调用其下的BuildCommand方法自动生成用于协调DataSet的更改与关联数据库的单表命令。

具体使用参看DataAdapter属性。

DataAdapter属性

只读属性。ITaoDataAdapter类型。通过它可以执行有返回数据库操作,并支持通过修改DataSet间接修改数据库的方法,即Update方法。

依赖:

a) 使用前需先指定数据库操作逻辑(通过ConnectionString, SQL属性指定或通过Command属性指定SQL语句)。

b) 使用Update方法时,在对DataSet进行修改之前需调用CommandBuilder.BuildCommand方法,且DataSet中必须包含主键。

1. 执行有返回的数据库操作

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

sql="select * from person";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

executeex.ConnectionString=constr;

executeex.SQL=sql;

DataSet ds=new DataSet();

executeex.DataAdapter.Fill(ds);

this.dataGrid1.DataSource=ds.Tables[0];

//

executeex.DataAdapter.Fill(ds,0,5,"person");

this.dataGrid1.DataSource=ds.Tables["person"];

2. 通过修改DataSet间接修改数据库的方法,即Update方法

constr="Data Source=Shark;Integrated Security=true;database=Northwind";

sql="select * From Employees";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.Sql);

executeex.ConnectionString=constr;

executeex.SQL=sql;

//获取包含主键的数据集

DataSet ds=new DataSet();

executeex.DataAdapter.Fill(ds);

//改变数据集之前须调用ICommandBuilder.BuildCommand方法

executeex.CommandBuilder.BuildCommand();

//更改DataSet中的数据(例如插入一条记录)

DataTable dt=ds.Tables[0];

DataRow newRow=dt.NewRow();

newRow["FirstName"]="Allen";

newRow["LastName"]="Tao";

newRow["TitleOfCourtesy"]="Mr.";

newRow["City"]="Beijing";

newRow["Country"]="China";

dt.Rows.Add(newRow);

//更新数据库

executeex.DataAdapter.Update(ds);

DataReader属性

只读属性。ITaoDataReader类型。通过它执行在线的数据库操作。

依赖:

a) 使用前需先指定数据库操作逻辑(通过ConnectionString, SQL属性指定或通过Command属性指定SQL语句)。

b) 当通过DataReader属性调用其下的属性或方法执行完操作后,必须调用其Close方法关闭数据库连接。

1. 执行在线的数据库操作

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

sql="select name from person";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

executeex.ConnectionString=constr;

executeex.SQL=sql;

string msg="";

while(executeex.DataReader.Read())

msg+=executeex.DataReader.GetString(0)+"/r/n";

executeex.DataReader.Close();

this.textBox1.Text=msg;

2. 使用Command.CommandBehavior属性

System.Data中的CommandBehavior枚举,提供对查询结果和查询对数据库的影响的说明。这个枚举值被用于IDbCommand.ExecuteReader 方法的参数。这里被设计成ITaoCommand的属性。

string constr=@"Provider=Microsoft.Jet.OLEDB.4.0;data source=c:/esec.mdb";

sql="select name from person";

Tao.Data.DataExecute.IExecuteEx executeex=new Tao.Data.DataExecute.Execute(Tao.Data.DataConfig.DatabaseType.OleDb);

executeex.ConnectionString=constr;

executeex.Command.CommandText=sql;

executeex.Command.CommandBehavior=CommandBehavior.SingleRow;

string msg="";

while(executeex.DataReader.Read())

msg+=executeex.DataReader.GetString(0)+"/r/n";

executeex.DataReader.Close();

executeex.Command.CommandBehavior= CommandBehavior.Default;//恢复为默认值

this.textBox1.Text=msg;

上面的代码中,指定executeex.Command.CommandBehaviorCommandBehavior.SingleRow枚举值,表明DataReader在操作时只要取一条记录,尽管SQL语句指定的可能是多条记录。

数据库类型的转换

在使用Execute类时,必须在实例化时指定数据库类型。在设计时,已尽量隐藏了数据库操作时对不同数据库类型所使用的类的区别,所用的主要措施是将数据库类型的差异由DatabaseType枚举值来体现。这样做的目的是使开发人员能集中精力在数据库操作逻辑与数据库功能上,而不必把精力花在该用哪个数据库类上。

在使用Execute类中唯一无法隐藏数据库类型差异的地方是ITaoParametersAdd方法的dbType参数,虽然它的类型是int,但在赋值要根据所用的数据库做一些变化。如用的是Access数据库时,这个参数赋值时就要用(int)OleDbType.XXX,而用的是SQL Server时,赋值时就要用(int)SqlDbType.XXX。为此要分别using的命名空间是System.Data.OleDbSystem.Data

当程序开发完成后,要改变所用的数据库类型时,只要改变上面提到的两个地方,即:

a) Execute类实例化时指定的DatabaseType枚举值;

b) ITaoParametersAdd方法的dbType参数。

MS Data Access Block的比较

最近我看了下面两篇文章:

l Microsoft Application Blocks for .NET Data Access Application Block 概述,http://www.microsoft.com/china/msdn/archives/library/dnbda/html/daab-rm.asp

l Data Access in .NET Architecture Guidehttp://msdn.microsoft.com/library/en-us/dnbda/html/daag.asp

并对Tao.DataMS Data Access Application Block(DAAB)进行了比较。

区别:

1. DAAB只适用于SQL Server .NET Data Provider,要用于其它数据库时必须另外开发一套版本。Tao.Data中使用DatabaseType枚举值作为构造函数的参数,目前可以支持Sql ProviderOleDB Provider,也可以很方便地扩展兼容其它的Provider。这样内嵌支持不同数据库类型,在数据库类型改变时对代码所做的改动会比较小。

2. DAAB中的SqlHelper类中提供的公开方法全是静态的,所以各个数据库操作对象之间不能有联系。Tao.Data中没有提供类似的静态方法,所以需要先实例化再使用,但各个数据库操作对象被组织成一个整体,方便进行统一的管理,比如连接字符串无需多次使用,Command可以多次使用等。

3. DAAB中可以选择输入ConnectionConnectionString,而Tao.Data中只能输入ConnectionString。这样做的目的是完全隐藏Connection对象,在内部负责OpenClose操作,避免用户出现只开不关的错误。唯一的例外是IExecuteDataReader属性,必须在使用完之后调用Close方法同时关闭DataReaderConnection,因为DataReader不能在断开连接的情况下进行操作。

4. DAAB中的SqlHelper类中各个方法需要SqlParameter数据组作为参数,并且提供了生成这样的数组的SqlHelprParameterCache类,Tao.Data中没有这样的功能,而是直接使用ADO.NET本身添加参数的方式。

相同点:

1. 都是对ADO.NET类的数据访问逻辑进行抽象,把几种固定的使用模式提取成方法以供调用。

2. 都从Command中抽取了ExecuteNonQuery,并提供了ExecuteDataSet方法作为*方法。

GotDotNet.DAAB 3.1的比较

http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=c20d12b0-af52-402b-9b7c-aaeb21d1f431

1. DAAB中没有把底层各个数据库之间的区别完全封装起来,用户是需要使用哪种对应数据库具体类的。Tao.Data中没有对外暴露这种类,而是根据枚举值进行内部转换。

2. DAAB的目的是encapsulate Microsoft's recommended best practices for data access in .NET applications, as described in the Microsoft Data Access Architecture Guide,因此它提供了比较高级的数据访问方式,比较完备;Tao.DataIExecute接口中提供有类似于DAABExecuteNonQueryExecuteDataSet方法,而在IExecuteEx中提供与ADO.NET中比较类似的访问方式。

3. DAAB中提供的方法比较完整,比如有对TransactionXMLReader的支持等;Tao.Data中还没有。

4. DAAB中对Data Provider之间的区别,比如SQL语句上的区别,SQL ServerOracle在参数表示上的区别(一个为@开头,一个为:开头),进行了兼顾;Tao.Data中没有考虑到这一点。