Chap 13 操纵数据源
---------------------------------
1、 采用断开连接的数据的优势:减少数据库连接资源的消耗,并且可以使用组件建立更好的应用程序
2、 DataTable的代码示例:
D:/Microsoft .Net程序练习/ASP.NET/chap13/rm416_datatable.aspx
3、 在这段代码中应注意:
(1) SqlDataAdapter对象使用Fill()方法,在DataSet中建立的“虚拟表”的名称是不同的,如果不指定表名,就使用数据库中的表名(默认)。其中每一个“虚拟表”就是一个DataTable
(2) 每个DataTable都存储为Tables集合的一部分
4、 DataTable可以包含多个行,每个行对应于从原数据源中检索出来的数据行。每个行用一个DataRow对象表示,存储在Rows集合当中
5、 可以使用下面的语句访问某DataTable中某DataRow中某字段的内容:
DataRow objDR;
string datarow;
datarow.Text=objDR.Rows[0][“字段名”].ToString();
6、 Rows集合从0开始索引,这使用的是C#的索引器(indexer)。索引器是一种特殊的属性,它可以访问集合中的项,就像它们是数组中的元素一样。上例[“字段名”]表示索引器
7、 添加、修改和删除DataTable中数据的代码示例:
D:/Microsoft .Net程序练习/ASP.NET/chap13/rm419_editingdata.aspx
8、 在这段代码中应注意:
(1) 在DataTable中增加行的时候,使用的是DataTable对象的NewRow()方法,然后分别对新行的各个字段赋值
(2) 在给各字段赋值之后,就要手工把新行添加到DataTable中,这要使用到DataTable对象的Rows集合的Add()方法。使用NewRow()方法只能创建一个新行,如果要同时添加两个新行,就要建立两个NewRow()对象
(3) 在添加数据后,这里需要注意,此时只是将新行添加到了DataSet中的某一个DataTable中,而不是原始数据源中,也就是说,若数据源(如DB)对某些字段做了限制(如非空限制),在此时不会起作用!这些约束只有在更新数据源的时候才会起作用
(4) 在DataTable中编辑行的时候,有两种方式定位一个待编辑的行:查找定位法(select)和索引定位法
(5) 在使用查找定位法的时候,必须先建立一个DataRow数组对象,以保存查找结果,因为select返回DataRow对象的一个数组(可能返回多行)。然后根据“行号[0]”和“索引[“firstname”]”分别更新此DataRow中的各字段即可
(6) 使用索引定位法无需指定“行号[0]”,因为在索引定位过程中指定的条件就是“行号”
(7) 在删除行的时候使用DataTable对象的Rows集合的Delete()方法。注意如果要删除最后两行,在写索引的时候,要写两次[objDT.Rows.Count-1],而不是写成[objDT.Rows.Count-1]和[objDT.Rows.Count-2],这会错误地删除其他行
(8) 同样也可以使用select()方法返回要删除的行
9、 Command对象和DataAdapter对象的区别在于,Command主要用于运行命令,而DataAdapter主要用于为多个命令提供一个存储空间!
10、 在运行操作数据库的增、删、改、查命令的时候,需要Command对象,但因为有四种不同的命令,所以要提供一个存储多个命令的方式
11、 DataAdapter使用4个属性存储Command对象,即存储用来执行不同类型的操作的命令。每个属性都是一个Command对象,因此就包含了Command对象的所有属性,例如CommandText和CommandType属性
12、 Command对象在操作数据库时候使用,但不必显式创建Command对象,在初始化一个DataAdapter对象的时候代码如下:
OleDbDataAdapter objDA=new OleDbDataAdapter(strSQL,objConn);
13、 工作过程如下:
(1) 自动创建一个Command对象
(2) 命令字符串(strSQL)被赋予Command对象的CommandText属性
(3) Connection对象(objConn)被赋予Command对象的Connection属性
(4) Command对象的CommandType属性被设置为Text
(5) Command对象被赋予DataAdapter对象的SelectCommand
14、 CommandBuilder对象用于让ADO.NET生成更新数据库的命令!它从SelectCommand属性中读取信息,确定其他的SQL语句的形式,并创建一个Command对象
15、 要注意:SelectCommand属性(包括其他InsertCommand属性等)是DataAdapter对象的!CommandText属性(包括其他CommandType属性等)是Command对象的!
16、 CommandBuilder对象的工作过程:
(1) 在初始化时以DataAdapter对象为参数
(2) 从DataAdapter对象的SelectCommand属性(生成一个Command对象)的CommandText属性获取一个用于查询数据库内容的select命令
(3) 根据select命令中的键字段名、字段名和表名,自动生成其余的增、删、改命令
(4) 将自动生成的命令分别赋给DataAdapter对象的增、删、改属性(分别返回Command对象)的CommandText属性
17、 CommandBuilder对象在自动生成SQL命令之前,必须要求提供给它一个“键字段”,否则命令不能生成
18、 CommandBuilder对象创建好了之后,就可以使用GetUpdateCommand()等方法,建立相应的命令,并把这些命令设置为DataAdapter的相应属性
19、 结合使用前面的修改DataSet中数据的功能和自动生成更新数据库命令的功能,将用户对DataSet中数据做出的改变写回数据库。这要使用到DataAdapter.Update()方法
20、 同步DataSet和源数据库的代码示例如下:
D:/Microsoft .Net程序练习/ASP.NET/chap13/rm431_synchronize.aspx
21、 在这段代码中应注意:
(1) 只要DataAdapter的4个属性(InsertCommand等)都用CommandBuilder对象的GetInsertCommand()等方法赋值之后,就可以开始同步DataSet和源数据库了
(2) 同步DataSet和源数据库使用DataAdapter的Update()方法,Update()方法带两个参数,应为:DataAdapter.Update(objDS,”TableName”);
(3) 在执行完DataAdapter.Update()方法后,源数据库中的数据就被更新了,而不需要显式地带开数据库连接
(4) 使用CommandBuilder对象可以减少代码的键入量,但CommandBuilder必须在程序运行时生成SQL命令,这比手工创建命令性能有所降低
22、 存储过程是一批SQL语句,它们被编写并编译好,存储在数据库服务器上,并有一个名称。可以按名称调用存储过程,而无需重新键入SQL语句。
23、 大多数数据库都预编译存储过程,所以它们通常要比编写的SQL语句效率高一些
24、 使用存储过程的代码示例:
OleDbCommand objComm=new OleDbCommand();
objComm.Connection=objConn;
//将需要调用的存储过程名称赋给Command对象的CommandText属性
objComm.CommandText=”[Sales by Category]”;
//将Command对象的CommandType属性设置为CommandType.StoredProcedure
objComm.CommandType=CommandType.StoredProcedure;
25、 有时应用程序在处理的时候不需要DataSet,如用户在网站上注册用户信息等,只需要在数据库中添加一行。这时直接运行一个SQL命令将更有意义
26、 直接对数据库执行SQL命令的代码示例:
strSQL=”insert into …”;
OleDbCommand objComm=new OleDbCommand(strSQL,objConn);
//用Command对象直接执行此SQL语句
objComm.ExecuteNonQuery();
27、 在这段代码中应注意:
(1) Command对象的ExecuteNonQuery()方法专门用于执行SQL语句,它没有返回值,因此ADO.NET无需建立存储数据的对象
(2) 也可以使用这种方式执行Update和Delete语句
28、 将DataSet中的(虚拟)数据表写入XML文件的代码示例:
objDA.Fill(objDS,”EMP”);
objDS.WriteXml(Server.MapPath(“Employees.xml”));
29、 在这段代码中应注意:
(1) 使用DataSet的WriteXml()方法,从DataSet的指定数据表中提取信息,格式化为XML,写入指定的XML文件当中
(2) 使用Server.MapPath()方法,返回指定文件的绝对路径
(3) 还有一个WriteXmlSchema()方法,用于写入XML模式
30、 读取XML文件中数据的代码示例:
DataSet objDS=new DataSet();
objDS.ReadXml(Server.MapPath(“Employees.xml”))
showdata.DataSource=objDS.Tables[0].DefaultView;
31、 在这段代码中应注意:
(1) 在读XML文件进入DataSet中的时候,没有指定读到Dataset中的虚拟数据表名,所以只能引用第1个表[0]
(2) 有一个对应的ReadXmlSchema命令,用于读取XML模式
32、 只要把XML加载到DataSet中,就可以使用对DataSet操作的任何方法进行操作。DataSet永远是DataSet,不用关心其中的数据是从什么数据源取得的!
33、 编辑XML文件中数据的代码示例:
//基本思路:读取——修改——回写
DataSet objDS=new DataSet();
objDS.ReadXml(Server.MapPath(“Employees.xml”));
DataTable objDT=objDS.Tables[0];
DataRow objDRnew=objDT.NewRow();
objDRnew[“lastname”]=”liu”;
objDRnew[“firstname”]=”dong”;
objDT.Rows.Add(objDRnew);
objDS.WriteXml(Server.MapPath(“Employees.xml”));