DataTable类

一、创建DataTable对象

前面已经学习了通过DataAdapterFill来生成DataTable对象,下面学习如何创建自己的DataTable对象,尤其是希望使用列级或表级限制来验证数据时。
1
、创建DataTable对象
可以采用创建DataSet对象的相同方式来创建DataTable对象。DataTable拥有一个可选构造函数,可用来设置DataTable对象的TableName属性。

 DataTable tb1 = new DataTable("学生");

            Console.Write(tb1.TableName);

           

2、向DataSet中的Tables集合中添加DataTable
在创建DataTable之后,可以利用DataTableCollection类的Add方法,将其添加到已有的DataSet对象的Tables集合中。

DataSet ds = new DataSet();

            DataTable tb1 = new DataTable("学生");

            ds.Tables.Add(tb1);

ado.ne还提供了一个更为简便的方法,通过重载DataTableCollection类的Add方法,将一个新的DataTable添加到DataSet对象的Tables集合中。可以在单次调用中创建一个DataTable并将其添加到一个现有的DataSet的Tables集合中。

 DataSet ds = new DataSet();

            DataTable tb1 = ds.Tables.Add("学生");

     可以通过检查DataTable对象的DataSet属性来确定一个DataTable是否存在于一个DataSet中。如果DataTable存在与一个DataSet对象的Tablese集合中,DataSet属性返回该DataSet。否则返回Nothing或Null,具体取决于所选择的语言。DataTable对象的DataSet属性是只读的。

     还有一点值得注意的是:一个DataTable至多可以存在一个DataSet中。如果希望将一个DataTable添加到多个DataSet对象中,必须使用Copy或Clone方法。Copy方法是以相同结构创建一个新的DataTable,其中包含的数据行与原来的DataTable相同。Clone方法以相同的结构创建一个新的额DataTable对象,但不包括原数据行。

3、向DataTable中添加Column
为了存储查询结果,DataTable中需要一些列。
我们曾经用代码向DataSet对象的Tables集合中添加一个新的DataTable,通过利用几乎与此相同的代码可以向DataTable对象的Columns集合中添加DataColumn对象。

DataSet ds = new DataSet();

            DataTable tb1 = ds.Tables.Add("学生");

            DataColumn col1 = tb1.Columns.Add("姓名");

            DataColumn col2=tb1.Columns.Add("性别");

4、为DataColumn指定数据类型。
可以用DataColumn的DataType属性来设置或检查列中的数据类型。
在向DataTable对象的Rows集合添加数据之前,DataColumn类的DataType属性是可读写的。

 DataColumn col2=tb1.Columns.Add("年龄",typeof(int));

5、添加主键
PrimaryKey
属性包含DataColumn对象的一个数组,所以不能简单地将这一属性设置为希望为主键值所使用的列的名称。
在所创建的DataTable对象中,一部分为单一列为主键值,而另一部分则以列的组合为主键。以下代码段包含了用于每一种情况的代码。Customers表使用单一列CostomerID,而Order Details表使用两个列的组合OrderIDProductID。这两种情况必须创建一个DataColumn对象数组,并将该数组赋值给DataTable对象的PrimaryKey属性。

DataSet ds = new DataSet();

            DataTable tb1;

            tb1 = ds.Tables.Add("Customers");

            tb1.Columns.Add("CustomerId"typeof(int));

            tb1.PrimaryKey = new DataColumn[] { tb1.Columns["CustomerID"] };

 

            DataTable tb2 = ds.Tables.Add("Order Dateils");

            tb2.Columns.Add("OrderID",typeof(int));

            tb2.Columns.Add("ProductID"typeof(int));

            tb2.PrimaryKey = new DataColumn[] { tb2.Columns["OrderID"], tb2.Columns["ProductID"] };

6、添加其它约束
主键是应用最为广泛的约束,但也可以向DataTable中添加唯一键和外键约束。DataTable类的Constraints集合有一个重载的Add方法,可用于添加新的主键值,唯一键和外键约束。

可以将重载的Add方法划分为不同类别。ConstraintCollection类的Add方法接受任何继承自Constraint对象的对象,所以可以提供UniqueConstraint对象或ForeighnKeyConstraint对象。因此,可以执行如下所示的代码:

DataTable.Constraints.add(New UniqueConstraint(…));

DataTable.Constraints.add(New ForeignKeyConstraint(…));

首先,看一个使用Add方法创建唯一约束的例子,第一个参数包含新的唯一约束的名称,第二个参数包含构成唯一约束的DataColumn(或DataColumn的数组)。第三个参数是一个Boolean值,用来确定新的约束是否被用于DataTable的主键值。
DataSet ds = new DataSet();

            DataTable tb1Customers = ds.Tables.Add("Customers");

            tb1Customers.Columns.Add("CustomerID"typeof(string));

            tb1Customers.Columns.Add("CompanyName"),typeof(string);

            tb1Customers.Constraints.Add("PK_CustomerID",tb1Customers.Columns["CustomerID"],true);

            tb1Customers.Constraints.Add("UK_CompanyName",tb1Customers.Columns["CompanyName"],true);

 

7、修改DataTable内容
1)、添加新的DataRow
DataTable
类拥有一个返回新的DataRow对象的NewRow方法,改对象包含表中每一列的相关信息。在创建了新DataRow之后,就可以使用其Item属性填充各列,还可以用Item属性查看行中列的内容。Item属性是DataRow类的默认属性,所以在使用Item时甚至不需要显示调用它。为了设置DataRow中一列的值,可提供该列的名称(或其索引或DataColumn本身),然后为其指定期望值。
DataTable
NewRow方法创建一个新行,但没有向DataTable中添加该行。
在为新行中所有的列提供了值,并为将其添加到DataTable准备就绪后,就可以使用DataRowCollectionAdd方法,并提供新行。

DataSet ds = new DataSet();

            DataTable tb1Customers = ds.Tables.Add("Customers");

            tb1Customers.Columns.Add("CustomerID"typeof(string));

            tb1Customers.Columns.Add("CompanyName",typeof(string));

            tb1Customers.Constraints.Add("PK_CustomerID",tb1Customers.Columns["CustomerID"],true);

            tb1Customers.Constraints.Add("UK_CompanyName",tb1Customers.Columns["CompanyName"],true);

            DataRow row =tb1Customers.NewRow();

            row["CustomerID"]="NEWCO";

            row["CompanyName"] = "New Customer";

            tb1Customers.Rows.Add(row);

DataRowCollection类的Add方法被重载,所以通过为新行提供列值清单而生成一个新的DataRow。其中RowState将被设置为Added。如下所示:

DataTable tb1 = new DataTable("Customers");

            tb1.Columns.Add("CustomerID"typeof(string));

 

            tb1.Columns.Add("CompanyName"typeof(string));

            tb1.Rows.Add("NewCo""New Cstomer");

 

DataTable类提供了第一种向表中添加数据的方法:LoadDataRow方法。此方法类似于被重载的Add方法,利用该方法可以为新的DataRow提供值清单,单它海让您控制新的DataRowRowState,要使用这一方法,在第一个参数中提供一个数组。该数组中的项对应于表中的列。第二个参数AccepteChanges控制新DataRowRowState属性,为这一参数传递False值,将会导致新行的RowStateAdded,就象前面示例中的通过调用DataTable.NewRowRows.Add来添加行。

DataTable tb1 = new DataTable("Customers");

            tb1.Columns.Add("CustomerID"typeof(string));

            tb1.Columns.Add("CompanyName"typeof(string));

            tb1.LoadDataRow(new object[] { "NEWCO""New Customer" },false);

在通过调用DataAdapter对象的Update方法向数据库中提交更改时,DataAdapter查看每个DataRowRowState,以确定如何更新数据库――――通过修改现有行、添加新行或删除现有行。如果向LoadDataRow中的第二个参数传递True值,新DataRowRowStateUnChange,这意味着该行不能包括DataAdapter将提交给数据库的挂起更改。

8、修改现有行

在拥有一个DataRow对象之后,可以使用DataRow对象的Item属性来设定一个列的值,在前面已经了解如何使用这一属性来查看一列的值。这一属性是可读写的,所以海可以使用它来设置一列的值。下面的代码使用Rows集合的Find方法来查找Customers DataTable中的一行,然后改变CompanyNameConstactName列的值。

DataTable tb1 = new DataTable("Customers");

            tb1.Columns.Add("CustomerID"typeof(string));

            tb1.Columns.Add("CompanyName"typeof(string));

            tb1.PrimaryKey = new DataColumn[] {tb1.Columns["CustomerID"]};

            tb1.LoadDataRow(new object[] { "NEWCO""New Customer" }, false);

            DataRow row = tb1.Rows.Find("NEWCO");

            if (row == null)

            {

                Console.Write("没有这个客户");

            }

            else

            {

                Console.Write("找到这个客户了,现在在修改");

                row["CompanyName"] = "new Value";

            }

 

第二种方法与第一种类似,只是添加了对DataRowBeginEdit方法和EndEdit方法的调用
 DataTable tb1 = new DataTable("Customers");

            tb1.Columns.Add("CustomerID"typeof(string));

            tb1.Columns.Add("CompanyName"typeof(string));

            tb1.PrimaryKey = new DataColumn[] {tb1.Columns["CustomerID"]};

            tb1.LoadDataRow(new object[] { "NEWCO""New Customer" }, false);

            DataRow row = tb1.Rows.Find("NEWCO");

            if (row == null)

            {

                Console.Write("没有这个客户");

            }

            else

            {

               

                Console.Write("找到这个客户了,现在在修改");

                row.BeginEdit();

                row["CompanyName"] = "new Value";

                row.EndEdit();

            }

使用BeginEditEndEdit可以对缓冲对数据行的更改,调用EndEdit保存对行的修改,如果确定不希望保存这些更改可以调用CancelEdit来撤销这些更改,该行将返回调用BeginEdit时的状态.

 

第三种方法

使用ItemArray属性。与Item属性类似,这一属性可用于获取或修改行的内容,这两个属性之间的不同在与Item属性每次处理一列,ItemArray属性返回和接受一个数组,其中每一项对应于一列。
如果希望在一行代码获取或修改多个行值,ItemArray属性非常方便。如果希望仅修改行中可用值的一个子集,清使用NullNothing(取决于所使用的语言)来指示不希望覆盖DataRow中的列的值。例如下面代码

DataTable tb1 = new DataTable("Customers");

            tb1.Columns.Add("CustomerID"typeof(string));

            tb1.Columns.Add("CompanyName"typeof(string));

            tb1.PrimaryKey = new DataColumn[] {tb1.Columns["CustomerID"]};

            tb1.LoadDataRow(new object[] { "NEWCO""New Customer" }, false);

            DataRow row = tb1.Rows.Find("NEWCO");

            if (row == null)

            {

                Console.Write("没有这个客户");

            }

            else

            {

 

                row.ItemArray = new object[] { null"New Value" };

            }

8、处理DataRow中的Null
DataRow
类具有一个IsNull方法,可以用它来查看一个列是否包含Null

9、删除DataRow
调用DataRowDelete方法即可。
但是,删除数据行并没有将其从DataTable中移除,而是标记为挂起删除。

10、移除DataRow 
如果确实希望DataTable移除一个数据行,而不是将其标记为挂起删除,可以使用DataRowCollection类的RemoveRemoveAt方法。如果拥有对一个欲删除的DataRow的引用,可以使用Remove方法。如果拥有该DataRow的索引号,则使用RemoveAt方法。

   DataTable tb1 = new DataTable("Customers");

            tb1.Columns.Add("CustomerID"typeof(string));

            tb1.Columns.Add("CompanyName"typeof(string));

            tb1.PrimaryKey = new DataColumn[] {tb1.Columns["CustomerID"]};

            tb1.LoadDataRow(new object[] { "NEWCO""New Customer" }, false);

            DataRow row = tb1.Rows.Find("NEWCO");

            if (row == null)

            {

                Console.Write("没有这个客户");

            }

            else

            {

                tb1.Rows.Remove(row);

               //or

                tb1.Rows.RemoveAt(tb1.Rows.IndexOf(row));

            }

此外,DataSetDataTable类各具有一个Clear方法,可以利用这一方法从DataSetDataTable中删除全部DataRow对象,同时保留其结构。

11、使用DataRow.RowState属性
DataSet
DataTableDataRow对象用作一种脱机处理数据缓存。可以查询数据库,并将结果存储在这些对象中。刚才已经了解到,可以添加、修改。和删除行。因为这些对象并没有连接到数据库,所以所做的变化将不会影响数据库中的内容。当然,如果不能在以后向数据库提交更改,那么脱机修改数据库的用途不是很大。

net支持将更改返回数据库。在后面,将深入理解这一功能,对于目前来说,只介绍有关DataSet如何支持这一功能的一些基础知识。为了将更改缓存到DataRow,以便Ado.net可以在以后将这些更改提交给数据库,Ado.net必须记住已经对该行进行何种类型的变化。为什么?

更新数据库中所存储的数据的一种方法是执行以下查询

Insert into mytable (field1,field2,…. Fieldn) values(values1,values2,…valuesn)

或者
 update Mytable set FieldToModify=NewValue where PKField=PkValue

或者
Delete from MyTable where PkField=PkValue

还可以通过存储过程,以类似方式进行更新。
关键在于,用于插入数据行的逻辑不同于用于修改数据行的逻辑,也不同于删除数据库的逻辑。因此,ADO.Net必须跟踪对DataRow进行了何种变化,以便在以后成功地将这些更改提交给数据库。

Ado.net将这些信息存储在DataRow中的一个RowState的属性中。可以使用DataRowState枚举中的值,来查看这一属性,可以确定该行数否已经被修改以及该行中所包含的更改类型(插入、修改、或删除)

常数

说明

Unchanged

2

该行未包含任何挂起更改

Detached

1

该行不是DataTable的一个成员

Added

4

该行已经添加到DataTable中,但不存在于数据库中

Modified

16

该行包含挂起更改

Deleted

8

该行为挂起删除

 

 12、控制DataRowRowState
我们已经研究了各种操作如何影响DataRowRowState,但如果希望更改RowState属性时应该怎么做呢?例如,您可能拥有一个DataRow,其RowStateUnchanged ,而您实际希望其
posted @ 2010-12-13 19:17  代码缔造的帝国  阅读(598)  评论(0编辑  收藏  举报