模拟在内存中的数据库DataSet相关的类
这篇连着上一篇DataReader相关类。
下面两段话是在msdn官网摘下来:
.NET Framework 数据提供程序是专门为数据操作以及快速、只进、只读访问数据而设计的组件。Connection 对象提供到数据源的连接。 使用 Command 对象可以访问用于返回数据、修改数据、运行存储过程以及发送或检索参数信息的数据库命令。 DataReader 可从数据源提供高性能的数据流。 最后,DataAdapter 在 DataSet 对象和数据源之间起到桥梁作用。 DataAdapter 使用 Command 对象在数据源中执行 SQL 命令以向 DataSet 中加载数据,并将对 DataSet 中数据的更改写回数据源中。
ADO.NET DataSet 是专门为独立于任何数据源的数据访问而设计的。因此,它可以用于多种不同的数据源,用于 XML 数据,或用于管理应用程序本地的数据。 DataSet 包含一个或多个DataTable 对象的集合,这些对象由数据行和数据列以及有关 DataTable 对象中数据的主键、外键、约束和关系信息组成。
说一下我对上图的理解,图中蓝色部分:可以在数据库中找到对应的映射对象(姑且让我这么说),黄色部分是C#里面为了操作数据方便,添加的类。
最近在学习ADO.NET Framwork类库:涉及到了DataSet相关的类,就想好好整理下一系列类的关系,其中涉及到的类从小到大有:
- DateColumn
- DataRow
- Constraint
- DataTable
- DataRelation
- DataSet
- SqlCommandBuilder
- DataAdapter
这些类都是用于在内存中模拟一个数据库,方便程序的直接操作,免去了多次连接数据库的时间耗费。
看到他们的名称就大概知道是做什么的,下面列一个表说明下他们的功能:
类名 | 功能 | 备注 |
DateColumn | 创建列,并设置相关属性(数据类型,列名,约束等) | 对应数据库中的列 |
DataRow | 根据列属性创建行数据(和数据库中的insert类似,但不一样) | 对应数据库中的行 |
Constraint | 设置或获取约束 | |
DataTable | 创建一个数据表,可以将DateColumn和DataRow的实例添加到数据表中 | 对应数据库中的数据表 |
DataRelation | 将两个表建立父子关系 | |
DataSet | 创建一个数据库,可以添加DataTable的实例 | 对应数据库 |
SqlCommandBuilder | 会自动构建对DataTable的insert,delete,updates操作Sql命令 | 还没想到备注 |
DataAdapter | 用于将数据源中的数据填充到DataSet或DataTable实例中, 并将操作最后的DataSet或DataTable实例,update到数据库中 | 还没想到备注 |
1、DataSet
DataSet的继承层次结构是:
这个类只是在内存中模拟出了一个数据库,其实质是一个集合也就是第一个图中的DataTableCollnection,数据表的集合。
1.1DataTable数据表
DataTable与数据库中table的区别:
DataTable是虚拟在内存中的数据表,不是持久化数据,而数据库中的数据是持久化数据,在调用DataAdapter对象的Update()方法之前,DataTable对象影响不了数据库中的数据表,也就是说Update()方法能将DataTable中的数据持久化到数据库中。
【这里最好看下本人博客中这篇DataTable的AcceptChanges()方法和DataRow的RowState属性】
得到DataTable对象的方式有很多,下面就列举下:
- 使用构造函数;
- 通过DataSet对象获取;
- 调用DataTable对象的Clone()方法获取表结构(不包含表数据)生成一个新的DataTable对象;
- 调用DataTable对象的Copy()方法获取表结构和表数据生成一个新DataTable对象;
DataTable常用的属性:
属性名 | 功能 | 返回值或设置值 |
CaseSensitive | 获取或设置表中数据是否区分大小写 | bool类型 |
ChildRelations | 获取该表子关系的集合 | DataRelationCollection类型 |
ParentRelations | 获取该表父关系的集合 | DataRelationCollection类型 |
TableName | 获取或设置该表的名字 | String类型 |
Columns | 获取该表中列的集合 | DataColumnCollection类型 |
Rows | 获取该表行的集合 | DataRowCollection类型 |
Constraints | 获取table中约束的集合 | ConstraintsCollection类型 |
DataSet | 获取该表所属的DataSet对象 | DateSet类型 |
DefaultView | 获取可能包含筛选视图或游标位置的自定义视图 | DataView类型 |
HasErrors | 获取一个值,该值表示该表所属的DataSet对象中的然后表的任何行中是否有错误 | bool类型 |
MinimumCapacity | 获取或设置该表的最初的起始大小 | int类型 |
PrimaryKey | 获取或设置充当该表主键的列的数组 | DataColumn[]类型 |
DateTable常用的方法:
方法名 | 功能 | 备注 |
AcceptChanges() | 保存对表的修改 | 参照【DataTable的AcceptChanges()和DataRow的RowState属性】 |
GetChanges() | 获取被修改【增删改】的行组成的表 | 一般会在AcceptChanges()方法前调用, 要不然Update()时会包空参数异常 |
Select() | 获取所有行组成的数组 | 返回值为DataRow[] |
GetChanges(DataRowState rowStates) | 获取指定状态位的行组成的表 | |
GetErrors() | 获取有错误的行的数组 | |
Clear() | 清空表数据,但是表结构和约束依然存在 | |
Clone() | 克隆表结构,包括约束,不包含数据 | |
Copy() | 复制表,包括结构约束,数据 | |
Compute(string expression, string filter) | 计算用来传递筛选条件的当前行上的给定表达式 |
1.1.1DataColumn数据列
类似于数据库中表的属性。
常用属性:
属性名 | 功能 | 返回值或设置值 |
AllowDBNull | 获取或设置该列是否可以为空(默认可以为空) | true说明可以为空 |
AutoIncrement | 设置或设置是否可以自增(默认不自增) | true说明是自增 |
AutoIncrementSeed | 设置自增列的初始值(默认为0) | long类型 |
AutoIncrementStep | 设置自增的步长(默认为1) | long类型 |
Unique | 设置该列中不允许有重复值(默认false,可以重复) | bool类型 |
DataType | 设置或获取该列存储的数据类型 | Type类型 |
DefaultValue | 在创建新行时获取或设置列的默认值 | object类型 |
ColumnName | 获取或设置该列的名字 | string类型 |
Table | 获得该列所属的DataTable对象 | DataTable类型 |
MaxLength | 获取或设置文本列能存储文本的最大长度 | int类型 |
ReadOnly | 获取或设置列的只读属性(默认值为false可读可写) | bool类型(默认false) |
Ordinal | 获取列在表中的位置(从零开始) | int类型(找不到就返回-1) |
Expression | 用于设置或获取表达式,用于筛选或计算列中值或创建聚合列 | string类型 |
1.1.2DataRow数据行
类似于数据库中表的元组。
常用属性:
属性名 | 功能 | 备注 |
HasErrors | 获取该行是否有错误 | 如果该行包含错误,则为 true;否则,为 false。 |
ItemArray | 获取或设置此行所有值 | 返回值为object[]数组 |
RowError | 获取或设置该行的自定义错误说明 | 返回值为string类型,是自定义的错误说明 |
RowState | 该行的状态(一共五个状态) | 参照【DataTable的AcceptChanges()和DataRow的RowState属性】 |
Table | 获取该行所属的表对象 | 返回值为DataTable类型 |
1.1.3DataView数据视图
类似于数据库中的视图。
常用属性:
属性名 | 功能 | 备注 |
Sort | 获取或设置 DataView 的一个或多个排序列以及排序顺序。 | |
2、SqlCommandBuilder
下面是DbCommandBuilder的继承层次图,不是SqlCommandBuilder的,
上图中的Odbc,OleDb,Oracle请看第三点DataAdapter介绍【连接数据库的发展历史】。
这个SqlCommandBuilder见名知意,他是一个Sql命令的建造者,用于生成Sql命令,它是根据DataTable中每行的RowState和数据表的主键来生成sql语句的,然后绑定SqlDataAdapter对象,当SqlDataAdapter对象调用Update()方法更新数据库时,他就会自动生成sql语句。
SqlCommandBuilder scb = new SqlCommandBuilder(adapter); //或者向下面这样 SqlCommandBuilder scb2 = new SqlCommandBuilder(); scb2.DataAdapter = adapter;
数据表的主键大家都知道,那这个每行的RowState是什么东西?
其实我们在对DataTable中的行进行增删改操作时,这些行都没有并没有被改动,而是其RowState这个属性被修改了,这属性是一个只读的枚举类型。
【详细的RowState请看本人博客中这篇DataTable的AcceptChanges()方法和DataRow的RowState属性】
【详细的SQLCommandBuilder构建T-Sql命令请看这篇SqlCommandBuilder构建T-sql语句】
3、DataAdapter
继承层次图:
图里面写到了ODBC,Ole,那我就理一下关于连接数据库的发展历史:
- odbc之前:使用的不同的数据库都有各自对应数据库访问API,领导说换数据库,那就需要修改源码,这会整死程序猿的;
- odbc时:定义了一个公共数据访问层,可以用来访问几乎所有的关系型数据库,各个数据库厂商提供相应的驱动即可;
- ole db时:基于odbc,不仅可以访问关系型数据库,还可以访问非关系型数据
- 那什么是ADO呢?ADO是面向对象的结果,能够做到和ole db一样,但比ole db更简单,也就是说,ADO将ole db中的方法封装成多个类,只要主要是九个类的使用;
- ADO.NET呢?这个中增加了一个SqlClient,专门用于访问SQL Server,也是它访问SQL Server最快。
我也是主要使用SqlDataAdapter这个类,如果论通用性,当然是使用OleDbAdapter会好一点。
下面就讲一下SqlDataAdapter这个类:
它有四个构造函数:
在这里也可以讲一下SqlDataAdapter和SqlDataReader的区别:
SqlDataAdapter的实例是一次将需要的结果集拿到内存中,并自动关闭数据库连接(以后数据库连接都称为conn);而SqlDataReader的实例是调用Reader()方法,它维持了一个指针的作用,一次读取一个元组并自动向下挪动一位,并且只能从结果集中的第一行开始,不能回头(上一篇博客有讲过SqlDataReader对象),而且在这个挪动指针读取元组的过程中,conn一直保持连接,需要手动去关闭,或者使用using代码块。如果只是要查询数据,使用SqlDataReader会更好一点,因为他速度比SqlDataAdapter要快。
SqlDataAdapter内部也是通过SqlDataReader拿取数据库的数据。
SqlDateAdapter用于将数据库中的数据填充到DataTable或者DataSet中
未完待续==================================