ADO.NET学习笔记-非链接类

1. DataTable类

DataTable类即是存在于内存中的表格式数据,包括行、列及约束,其中行主要用于存储数据,而列和约束共同组成DataTable的Schema(架构)。

2. 创建主键组合列

主键可以一列构成,也可由多列构成,统一起见,ADO.NET在创建主键时,都使用列数组,例:

cars.PrimaryKey = new DataColumn[] { vin };

3. 使用自增长列做为主键

在应用程序中设置自增长列的方法如下:

1) 将列的AutoIncrement属性设为true

2) 将列的AutoIncrementSeed设为-1

3) 将列的AutoIncrementStep设为-1

第二、第三步设为-1的原因为,在多个客户端同时生成数据传回数据库时,极可能出现数据冲突,抛出异常,如将Seed和Step设为-1,则应用程序生成的编号永远为负数,避免了与数据库编号相冲突。

4. 向DataTable添加数据(DataRow)的方法

DataTable拥有一个Rows属性,返回一个DataRowCollection对象。向DataTable添加数据,即是向DataRowCollection中添加DataRow。添加的方法大致有三种:

1) DataRow newCar = cars.NewRow();

newCar["Vin"] = "123456789ABCD"

cars.Rows.Add(newCar);

2) cars.Rows.Add("123456789ABCD");

3) cars.LoadDataRow(new object[] {"123456789ABCD"}, LoadOption.OverwriteChanges);

其中第三种方法,使用DataTable.LoadDataRow()方法,是“查找并更新行”的意思,如果没有查找到相关行,则创建这个行。

5. 数据行版本(DataRowVersion)的4个枚举类型值

为了向数据使用者提供数据行在不同状态下的值,数据行(Data Row)拥有3种基本版本状态,即Original,Current和Proposed,当然还有第4种,Default。当数据行刚被载入时,它只有一个版本状态,即Current(并非Original,Original即意味着有改更发生),此时的Default为Current;当执行了BeginEdit方法后,数据行进入更改模式,更改后的数据作为一个新的实例存在,其版本状态称作Proposed,此时的Default为Proposed;执行了EndEdit方法后,Proposed变为Current,而原先的Current变为Original,Proposed就不存在了,此时的Default为Current。再次调用BeginEdit方法后,Current变为Proposed,Default为Proposed; 再调用EndEdit方法,Proposed变为Current,Proposed不存在了,但要注意,Original这次没有变化,还是当初载入的那一个,此时的Default为Current。即Original保留上一次载入或是最近一次AcceptChanges方法调用后的那个值。

另需注意,DataRow的DataRowVersion属性值(通过HasVersion(Version)方法获得)与其DataRowState属性值相关联,如Original只在DataRow的状态变为Modified, Unchanged或Deleted时有意义,而在Added状态下,会抛出异常(DataRow.HasVersion(Original))。

6. AcceptChanges和RejectChanges方法

这两个方法同时存在于(可用于)DataSet, DataTable和DataRow对象,明显的,在DataSet上执行方法时,其包含的所有DataTable和DataRow均会受到影响,反之,如果只在某个特定的DataRow上执行此方法,则其父辈的DataTable和DataSet不受任何影响。

一般情况下,载入数据后,DataRow的状态(State)为Added,此时调用AcceptChanges或RejectChanges方法,则DataRow的状态变为Unchanged,再改变一下DataRow的值,其状态又变为Changed。调用一下AcceptChanges,则产生一个Original版本,当然如果调用RejectChanges,则不会产生Original版本,只有一个Current版本。

在完成数据编辑后,可以调用DataTable的GetChanges方法,返回一个DataTable,其中的内容仅为自上次AcceptChanges方法调用后变动过的DataRow行,这样回传至远程数据库时,数据量就要小得多。

需注意:

1) 当数据与数据库成功同步后,一定要调用AcceptChanges方法将DataRow的值统一设置为Unchanged,以与远程数据库同步。

2) 当调用RejectChanges时,Original里的值要拷贝至Current,以还原Load时的初始状态或是上一次调用AcceptChanges后的状态。

7. 使用SetAdded或SetModified将行状态强行设置为Added或Modified

在某些情况下,需要将行(DataRow)的状态改为Added或Modified以便DataAdapter有效识别并上传至远程服务器。需要注意的是,这两个方法均只能使用在DataRow对象上,且需保证DataRow的状态为UnChanged,否则会出错。使用SetAdded方法时,会丢弃DataRow的Original状态值,因为一个具有Added状态的行,是不可能有Orginal状态值的。

8. 删除和恢复

使用行(DataRow)的Delete方法可将需删除的行标注出来(但并未真正删除),些时此行的Current和Proposed状态值被丢弃,如果此时调用调用RejectChanges方法,则Original状态值被拷贝至Current,其状态变为Unchanged,但自load或AcceptChanges调用以来的所有更改均舍弃,若调用AcceptChanges方法,行被真正删除,再引用此行会抛出异常。

9. DataTable的复制和克隆方法

复制和克隆在中英文中并没有什么区别,但作为DataTable的两个方法,二者区别明显。Copy方法用于复制表格的结构和数据,而Clone方法仅复制表格的结构,而不复制数据。

10. 行版本和行状态的区别

DataRow有版本(Data Version)和状态(Data State)的区别,其中版本有4个,即Original, Current, Proposed, Default;而状态有5个,即Detached, Added, Deleted, Unchanged, Modified。版本和状态是同时存在的,但其任意组合并不是一定存在。如行被Deleted以后,其Current和Proposed数据均被丢弃,只剩下Original供还原时使用。

11. DataViewRowState枚举对象

这个枚举对象听名字好像只与状态相关,其实是版本与状态的结合,其包含有8个状态:

Added, CurrentRows(相当于Added|Unchanged|ModifiedCurrent), Deleted, ModifiedCurrent, ModifiedOriginal, None, OriginalRows和Unchanged

12. DataView的输出问题

先看代码:

static void PrintView(DataView dv)

{

StringBuilder buffer = new StringBuilder();

foreach (DataColumn dc in dv.Table.Columns)

buffer.AppendFormat("{0, 15}", dc.ColumnName);

foreach (DataRowView dr in dv)

{

buffer.Append("\n");

foreach (DataColumn dc in dv.Table.Columns)

buffer.AppendFormat("{0, 15}", dr.Row[dc]);

}

Console.WriteLine(buffer.ToString());

}

红色标注部分为重点。可以看出,对列的读取,可取视图的表格属性,再取其列;但对于行,如果也用其表格属性再取其行,则其所做的筛选信息将全部丢失,所以只能使用DataRowView对象(可以看出,其实DataView就是DataRowView的集合)。

当然,我们也可以将DataView转换为DataTable,然后再用我们熟悉的方法输出,但转换产生的开销比较大,用多了自然会影响效率。

13. DataSet对象

DataSet可看成是内存中的数据库,但其本身与数据库的差别还是很大的,这是后话。DataSet包含一组DataTable对象和一组DataRalation对象,DataTable对象本身可包含唯一键及外键,用以保证数据完整性。

我们可以使用手工编程的方法创建DataSet对象,也可以使用XSD(XML schema Definition)文件创建强类型的DataSet对象,后者更简单,更常用。

14. DataRelation对象

DataRelation对象用以将DataSet对象内的多个DataTable对象关联起来,其作用相当于数据库中的表间关系。在创建DataRelation对象时,我们可以指定主键及外键约束,如在下面的语句中:

ds.Relations.Add("vendor_parts", vendors.Columns[0], parts.Columns[2]);

ds.Relations.Add("vendor_parts", vendors.Columns[0], parts.Columns[2], true);

两条语句的作用一样,只是第二条语句指定了createConstraints这个布尔值,即是否在父表中创建主键约束,在子表中创建外键约束,默认为true,这也符合我们一般的需求。

另一个有用的默认值为创建级联完整性约束(Cascade),默认为Rule.Cascade。

15. 合成DataSet数据

DataSet数据合成在程序中非常常见。

16. Path类

Path类存在于System.IO命名空间,用于处理文件及文件夹路径操作,拥有跨平台的特点和好处,其常用方法为:Path.Combine(Param string[] paths),用作将多个paths联成一个整体的Path。

17. 序列化 (Serialization)和逆序列化(Deserialization)

序列化即是将DataSet中的数据保存为xml或是bin(流)文件存放在本地,而逆序列化正好相反,从本地的xml或是bin(流)文件中读入构架和(或)数据,生成DataSet。以xml文件为例,序列化使用DataSet.WriteXml()方法,逆序列化使用DataSet.ReadXml()方法。

18. 序列化为xml文件

上面已经提到过,序列化为xml文件时,使用DataSet的WriteXml()方法,此方法需2个参数,一个是要保存的文件名,要全路径名,另一个是序列化类型尾数,是一个枚举值,有3个,分别为WriteSchema(架构+数据),IgnoreSchema(仅数据)和DiffGram(含Original和Current值)。要修改xml文件中的显示方式和内容,可做相应个性,如要改变表格名称,可修改DataTable的TableName属性;要修改各列在xml中的显示方式,可修改各列的ColumnMapping属性(ColumnMapping属性仅对生成的XML文件起作用)。其中ColumnMapping的值有4个,分别为Attribute, Element, Hidden, SimpleContent。其中Attribute和Element与Xml语法相关。

19. 将更改过的DataSet保存(序列化)为xml文件(使用XmlWriteMode.DiffGram)

格式如下:

cars.WriteXml(desktopFileName("cars.xml"), XmlWriteMode.DiffGram);

这里的DiffGram保存了所有的DataRowVersion信息。利用此格式的XML文档保存和恢复DataSet将不会有信息丢失。

20. 从文件创建DataSet(Deserialize,逆序列化)

需要特别注意的是,如果没有提供架构信息,则所有的数据都会被当成是字符数据,所以在从XML读取数据前,一定要先载入架构信息。

示例代码如下:

DataSet ds = new DataSet();

ds.ReadXmlSchema(desktopFileName("cars.xsd"));

ds.ReadXml(desktopFileName("cars.xml"), XmlReadMode.IgnoreSchema);

其中的XmlReadMode枚举值有:Auto(自动选择合适的值),DiffGram(见19点),Fragment(作为片段读取),IgnorSchema(不读取架构信息),InferSchema(自动推断架构信息),InferTypedSchema(自动推断,但新加项不再为string),ReadSchema(加载xml文档中的架构信息,如果没有架构信息,则抛出异常)

21. 使用DataTableReader类循环读取数据

DataTableReader类用于迭代一个或多个数据表(DataTable)中的数据行(DataRow),返回的行数据只读、只进(Read Only & Forward Only),换言之,在迭代过程中,你可以往DataTable中添加或删除数据,如果修改的数据在指针(Position Cursor)以前,则修改的数据就不管了,但如果修改的数据在指针以后,则修改的数据要反映出来。当指针到达行末尾时,Read方法返回Null。语法如下:

DataTableReader rd = cars.CreateDataReader();

while(rd.Read())

{

do something;

}

rd.NextResult();

while(rd.Read())

{

do something;

}

时间: 2024-11-06 12:38:34

ADO.NET学习笔记-非链接类的相关文章

angular学习笔记(九)-css类和样式2

在上一个例子中,元素的类名使用拼接的方法,这样,类名中就不得不带有true或false,并且不易维护,所以,angular使用ng-class属性来控制元素的类名: 我们来看一个小例子,点击error按钮,顶部提示错误框,点击warning按钮,顶部提示警告框. 错误框的类名是.err,警告框的类名是.warn: <!DOCTYPE html> <html ng-app> <head> <title>6.2css类和样式</title> <

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详细,自己在看它的文档和代码时写了一些demo和笔记,还有它实现的原理记录一下 学习Caliburn.Micro要有MEF和MVVM的基础 先说一下他的命名规则和引导类 以后我会把Caliburn.Micro的 Actions IResult,IHandle ICondu

angular学习笔记(九)-css类和样式3

再来看一个选择li列表的例子: 点击li中的任意项,被点击的li高亮显示: <!DOCTYPE html> <html ng-app> <head> <title>6.3css类和样式</title> <meta charset="utf-8"> <script src="../angular.js"></script> <script src="scri

C++ Primer Plus学习笔记之继承类的初始化顺序

C++ Primer Plus学习笔记之继承类的初始化顺序 基类的构造函数,析构函数和操作符函数operator=是不能被派生类继承的: 那么,当创建一个派生类对象时,怎样调用基类的构造函数对基类的数据进行初始化呢??? 答案是:构造函数执行时遵行先兄长(基类),再客人(对象成员),后自己(派生类)的顺序: 另一方面,执行析构函数时,先执行派生类的析构函数,再执行基类的析构函数.原因是,对基类的破坏隐含了对派生类的破坏,所以派生类的析构函数必须先执行: #include<iostream> u

Lua学习笔记4:类及集成的实现

-- Lua中类的实现 -------------------------------- 基类 ---------------------------- classBase = {x = 0,y = 0} -- x,y为类的成员变量 classBase.__index = classBase -- 这句是重定义元表的索引,必须要有 --模拟构造体,一般名称为new() function classBase:new(x,y) local self = {}     -- 初始化对象自身 setme

ADO.NET学习笔记之连接字符串

ADO.NET 2.0学习笔记之连接字符串 刚刚入门不久,想什么学习下dot net平台,就先从数据访问入手吧,从今天开始认真学习ado.net 2.0,为将来发展做好坚实基础. 连接字符串 SQL Client .net数据提供程序在连接到数据库时极其灵活,它提供了多种用以生成连接字符串的方式.可以使用关键字,例如“Data Sourse”.“Initial Catalog”,也可以使用"Server".“Database”等旧术语. 下面是两个例子,用于连接到SqlServer数据

非专业码农 JAVA学习笔记 6java工具类和算法-string

续<非专业码农 JAVA学习笔记 5 java工具类和算法> 五.字符串string 字符串和字符的差别:字符串双引号括起来”n”,字符用单引号括起来,表示一种符号’\n’ 1.string的主要方法和属性 类 方法或者属性 备注 定义string Stirng s=new string(“值”),string s=”值” 属性 string.length:string的长度为字节 方法startswith,endswith s.startwith(“值”)-以值为开头,s.endswith(

ADO.NET学习笔记-链接到Data Store

1. 使用数据提供程序(Providers)移动数据 .NET默认包含的数据提供程序有以下4种: OleDb odbc SQL Server Oracle 除此之外还可使用第三方数据提供程序,如Mysql和DB2等.数据提供程序的主要功能为在本地程序和远程数据源(Data Store)之间移动数据. 2.DbConnection对象 要获取数据,首先要有一个合法可用的数据链接(Connection),数据链接的抽象类为DbConnection,再由数据提供程序的不同继承生成对应的具体数据链接类,

ADO.NET 学习笔记 入门教程

本文转载自:http://www.youarebug.com/forum.php?mod=viewthread&tid=57&page=1&extra=#pid63 这是本人在学习ADP.NET过程中所作的笔记,可作为ADO.NET入门或者复习的教程. 连接字符串: DataSource=localhost; AttchDBFilename=|DataDirectory|\Database1.mdf; InitialCatalog=UserDate; Integrated Secu