6.6.1 DataSet对象的属性
CaseSensitive
DataSetName
DesignMode
EnforceConstraints
ExtendedProperties
HasErrors
Locale
Namespace
Prefix
Relations
Tables
6.6.2 DataSet对象的方法
AcceptChanges:
RowState的属性值为Added或Modified的所有行的RowState属性将会被设置为Unchanged。这样做也会将DataRow的当前值重置为原始值。任何标记为Deleted的DataRow对象在调用AcceptChanges时将会被删除。
DataAdapter对象成功地提交存储在DataRow对象中的挂起更改时,它也隐式地对该DataRow调用了AcceptChanges。
BeginInit
Clear
Clone
Copy
EndInit
GetChanges
GetXml
GetXmlSchema
HasChanges
InferXmlSchema
Merge
ReadXml
ReadXmlSchema
RejectChanges
Reset
WriteXml
WriteXmlSchema
6.6.3 DataSet对象的事件
MergeFailed
6.6.4 DataTable对象的属性
CaseSensitive
ChildRelations
ParentRelations
ChildRelations属性和ParentRelations属性允许您查看当前DataTable中包含子关系或父关系的DataRelation对象。
假设您正在处理分级的Customer数据,Order数据和OrderDetails数据,并引用了一个包含Order信息的DataTable,那么ParentRelations集合将会包含关联Order DataTable和Customer DataTable的DataRelation对象;ChildRelations将会包含涉及Order DataTable和OrderDetails DataTable的DataRelation对象。
Columns
Constraints
DataSet
DefaultView
如果您为DataTable绑定一个控件,则该控件实际绑定到DataTable的DefaultView属性上。例如,可以用下面的代码来应用过滤器,使得在绑定到DataTable的DataGrid中只显示来自西班牙的客户,DataTable仍包含所有的客户。
tblCustomers.DefaultView.RowFilter = "Country = 'Spain'";
gridCustomers.DataSource = tblCustomers;
DesignMode
ExtendedProperties
HasErrors
Locale
MinimumCapacity
如果大概知道DataTable包含的行数,那么在将结果填充到DataTable前设置DataTable对象的MinimumCapacity属性可以起到增强代码性能的结果。
MinimumCapacity默认为50
Namespace
Prefix
PrimaryKey
2个作用,一个是作为唯一约束,另一个是使用DataTable的Rows集合的Find方法还可以根据DataRow中的主键在DataTable中定位在DataRow。
Rows
TableName
6.6.5 DataTable对象的方法
AcceptChanges
BeginInit
BeginLoadData
如果要将一组DataRow对象添加到DataTable对象中,那么使用BeginLoadData和EndLoadData方法也许能够改进性能。
调用BeginLoadData会关闭DataTable的约束,调用EndLoadData将恢复约束。如果DataTable包含破坏约束的行,那么在调用EndLoadData时会出现ConstraintException。要确定引发异常的行可查看GetErrors方法返回的行。
Clear
Clone
Compute
可以使用该方法在特定查询规则基础上执行对DataTable中某一列的聚合查询。
下面代码介绍了使用Compute方法来计算包含chai的定单数。代码还计算订购chai的单位总数:
string strSQL, strConn;
strConn = "Provider=SQLOLEDB;Data Source=(local)\\NetSDK;" +
"Initial Catalog=Northwind;Trusted_Connection=Yes;";
strSQL = "SELECT OrderID, ProductID, Quantity FROM [Order Details]";
OleDbDataAdapter da = new OleDbDataAdapter(strSQL, strConn);
DataTable tbl = new DataTable("Order Details");
da.Fill(tbl);
int intNumChaiOrders;
Int64 intNumChaiUnits;
intNumChaiOrders = (int) tbl.Compute("COUNT(OrderID)",
"ProductID = 1");
intNumChaiUnits = (Int64) tbl.Compute("SUM(Quantity)",
"ProductID = 1");
Console.WriteLine("# of orders that include chai: " +
intNumChaiOrders);
Console.WriteLine("Total number of units ordered: " +
intNumChaiUnits);
不能使用Compute方法来计算包括多列的聚合——如SUM(Quantity*UnitPrice),但可使用基于表达式的列来执行两列的计算,接着在Count方法中使用基于该表达式的列——SUM(ItemTotal)。
Compute方法通过使用通常的Object数据类型来返回结果,因此当使用Compute方法执行计算时,用来存储结果的数据类型可能会令您吃惊。例如Quantity列的数据类型属性是16位的整数,但调用Compute方法返回的是64位整数。
如果不能确定调用Compute方法时存储结果的数据类型,可以使用下面的代码:
object objRetVal = tbl.Compute("SUM(Quantity)",
"ProductID = 1");
Console.WriteLine(objRetVal.GetType().ToString());
Copy
EndInit
EndLoadData
GetChanges
GetErrors
ImportRow
LoadDataRow
NewRow
ImportRow接受DataRow对象,并将数据添加到DataTable中。
LoadDataRow方法会接受任一数组作为它的第一个参数。数组中的每个项对应DataTable的列集合的一项。LoadDataRow的第二个参数是控制新DataRow对象的RowState的Boolean值。如果希望是Added,应该置false,如果希望是Unmodified,设置为true即可。
NewRow方法会为DataTable返回一个新DataRow对象,此时新DataRow将不会存储在DataTable的Rows集合中,当已经将所需的列加入DataRow后,需要将这项添加到Rows集合中。
应该用哪种方法,建议如下:
如果不希望从不同DataTable中导入行,使用ImportRow方法。
如果希望根据文件内容一次添加若干行,使用LoadDataRow。
其他情况下,使用NewRow
RejectChanges
Reset
Select
可以使用select方法根据各种搜索条件来定位DataTable的一行或多行,Select方法会返回符合条件的一组DataRow对象。
6.6.6 DataTable对象的事件
ColumnChanged
ColumnChanging
RowChanged
RowChanging
RowDeleted
RowDeleting
6.6.7 DataColumn对象的属性
AllowDBNull
AutoIncrement
AutoIncrementSeed
AutoIncrementStep
Caption
如果在绑定的数据网格中显示DataTable的内容,可使用Caption属性来控制列的标题。在默认情况下,Caption属性将返回与ColumnName属性值相同的值。
ColumnMapping
当DataSet数据以xml返回时,可以使用ColumnMapping属性来控制ADO.NET如何写入列的内容。
ColumnMapping属性接受System.Data命名空间中的MappingType枚举的值。ColumnMapping属性默认值为Element,即表示DataRow中每一列的值都会显示在一个元素标签中。还可以将ColumnMapping属性设置为Attribute、Hidder或SimpleContent。
下面的例子表明了使用元素和使用DataSet中数据属性的区别。
Using Column.ColumnMapping = MappingType.Element
<MyDataSet>
<Customers>
<CustomerID>ABCDE</CustomerID>
<CompanyName>New Customer</CompanyName>
<ContactName>New Contact</ContactName>
<Phone>425 555-1212</Phone>
</Customers>
</MyDataSet>
Using Column.ColumnMapping = MappingType.Attribute
<MyDataSet>
<Customers CustomerID="ABCDE" CompanyName="New Customer"
ContactName="New Contact" Phone="425 555-1212" />
</MyDataSet>
ColumnName
DataType
默认设置为存储字符串。DataType属性接受Type属性的值。下面代码介绍了如何直接设置DataColumn对象的DataType属性和调用DataColumnCollection对象的Add方法。
DataColumn col = new DataColumn("NewColumn");
col.DataType = typeof(Decimal);
DataTable tbl = new DataTable("Products");
tbl.Columns.Add("ProductID", typeof(int));
tbl.Columns.Add("ProductName", typeof(string));
tbl.Columns.Add("UnitPrice", typeof(Decimal));
DefaultValue
Expression
可以将表达式存储在该属性中,并且每次请求列的内容时都会计算该表达式。只要不将该属性设置为默认空字符串,就会自动将DataColumn的ReadOnly属性设置为true。
下面代码介绍了如何设置DataColumn的Expression属性来返回DataTable中两列的乘积。
DataTable tbl = new DataTable("Order Details");
tbl.Columns.Add("OrderID", typeof(int));
tbl.Columns.Add("ProductID", typeof(int));
tbl.Columns.Add("Quantity", typeof(int));
tbl.Columns.Add("UnitPrice", typeof(Decimal));
DataColumn col = new DataColumn("ItemTotal", typeof(Decimal));
col.Expression = "Quantity * UnitPrice"
tbl.Columns.Add(col);
DataRow row = tbl.NewRow();
row["OrderID"] = 1;
row["ProductID"] = 1;
row["Quantity"] = 6;
row["UnitPrice"] = 18;
tbl.Rows.Add(row);
Console.WriteLine(row["ItemTotal"]);
ExtendedProperties
MaxLength
默认为-1。
Namespace
Ordinal
返回DataColumn在DataTable对象的列集合中的位置,该属性只读,并且如果DataColumn不在DataTable对象的Column集合中,返回-1。
Prefix
ReadOnly
如果设置了true,但只要是在将列内容添加到DataTable对象的rows集合前,仍然可以修改该列的内容。
Table
Unique
将该属性设置为true将隐式地为列所在的DataTable创建一个UniqueConstraint对象。类似地,给一列添加UniqueConstraint也会将该列的Unique属性设置为true。
如果创建一组列的唯一约束或主键,则每个DataColumn的属性都不会被设置为true,因为列中的值不一定是唯一的。
6.6.8 DataRow对象的属性
HasErrors
Item
ItemArray
RowError
RowState
Table
6.6.9 DataRow对象的方法
AcceptChanges
BeginEdit
CancelEdit
ClearErrors
Delete
实际上并不真正删除。如果希望彻底删除,可以先调用delete方法,然后调用AcceptChanges。
EndEdit
GetChildRows
获得当前DataRow的子行。要使用该方法,必须提供一个DataRelation或是该DataRelation的名称。还可以提供DataRowVersion枚举中的值来控制获取数据的版本。
该方法返回一组DataRow对象中的子数据。
GetColumnError
SetColumnError
GetColumnsInError
GetParentRow
GetParentRows
SetParentRow
GetParentRow和SetParentRow提供了一种简便的方法来分别查看和设置DataRelation对象中当前行的父行。
同GetChildRows方法一样,GetParentRow接受DataRelation名称或对象本身。也接受DataRowVersion枚举中的值来控制获取数据的版本。GetParentRow方法返回一个DataRow对象。
如果当前DataRow有多个父行,可以使用GetParentRows方法访问那些行。
调用SetParentRow可以修改关系中的父行,使用该方法只需要传递该行的新的父行。如果当前行的DataTable是DataSet中多个关系的字表,则必须使用允许将DataRelation对象作为第二个参数传递的重载方法,这样SetParentRow方法才能知道希望引用的是哪个关系。
HasVersion
是否具有某一版本的值。(该版本是DataRowVersion枚举中的值)
IsNull
假设您正在处理包含客户信息的DataRow,并希望将获取的ContactName列内容赋给一个字符串变量,如果使用下面的代码,且ContactName列包含Null值,则有可能出现问题。(注意:强类型DataSet中确实存在的)
DataRow row;
。。。。
string strContactName;
strContactName = (string) row["ContactName"];
要避免上面的问题,可以有2种方法:创建的数据库和数据集的列不支持null值,或在列的内容之前查看列中是否有null值。
IsNull正是为第二种方法准备的。
RejectChanges
6.6.10 UniqueConstraint对象的属性
Columns
ConstraintName
ExtendedProperties
IsPrimaryKey
Table
6.6.11 ForeignkeyConstraint对象的属性
AcceptRejectRule
DeleteRule
UpdateRule
这3个属性控制父行的修改怎样影响子行。
AcceptRejectRule接受AcceptRejectRule枚举中的值。该属性默认值为None,即表示如果对行调用AcceptChanges方法或RejectChanges方法,子行不会受到影响。如果设置为Cascade,该操作会根据ForeignkeyConstraint对象中定义的规则级连其子行。
DeleteRule和UpdateRule属性很相似,都接受Rule枚举中的值,两个属性的默认值都是Cascade,表示父行的更改会自动级连到字行。
如果不希望级连,也可以将DeleteRule和UpdateRule属性值设置为None。还可以将它们设置为SetDefault或SetNull。设置SetNull的话,父行被删除或其相关联的列的内容被改变时,子行中相关联的列的内容则为null。SetDefault和SetNull差不多,只不过子行中相关联的列的内容被设置为其默认值。
Columns
ConstraintName
ExtendedProperties
RelatedColumns
RelatedTable
Table
回顾Chap.6 处理DataSet对象(2)
6.5 修改DataTable内容
6.5.1 添加新DataRow
DataTable对象有一个返回新DataRow对象的方法,该对象包含了表中每一列的信息。
DataRow row=ds.Tables[“Customers”].NewRow();
row[“CustomerID”]=”ALFKI”;
创建新的DataRow后,就可以使用它的item属性来填充不同的列,还可以使用item属性检查行中列的内容。
DataTable的NewRow方法创建一个新行,但并不会将该行添加到DataTable中。通常由于刚创建的行是空行,所以在新行刚创建时您并不希望添加新行。如果列没有默认值,该列就被设置为Null。
一旦给新行所有需要的列赋值后,就可以使用DataRowCollection的Add方法来将新行添加到DataTable中。如下:
ds.Tables[“Customers”].Rows.Add(row);
DataTable对象还提供了另一种方法来将新行添加到表中:LoadDataRow方法。使用该方法,需要给第一个参数提供一组数值,数组中的数值项与表中的列相对应;AcceptChanges是LoadDataRow方法的第二个参数,它允许控制新行DataRow的RowState属性值。下面代码中该值为false,则新行的RowState属性值为Added。
Object[] aValues={“ALFKI”,”alfreds Futterkiste”,”Maria Anders”,”030-0074321”};
ds.Tables["Customers"].LoadDataRow(aValues, false);
如果第二个参数的值为true,则新DaraRow的RowState值将为Unmodified,即表示该行不包含DataAdapter要提交给数据库的挂起更改。
6.5.2 修改当前行
有3种方法可以修改当前行。
1) 使用DataRow对象的item属性对列赋值。
DataRow rowCustomer;
rowCustomer = ds.Tables["Customers"].Rows.Find("ANTON");
if (rowCustomer == null)
//Customer not found!
else {
rowCustomer["CompanyName"] = "NewCompanyName";
rowCustomer["ContactName"] = "NewContactName";
}
2) 与第一种类似,只是添加了BeginEdit 和 EndEdit 方法
DataRow rowCustomer;
rowCustomer = ds.Tables["Customers"].Rows.Find("ANTON");
if (rowCustomer == null)
//Customer not found!
else {
rowCustomer.BeginEdit();
rowCustomer["CompanyName"] = "NewCompanyName";
rowCustomer["ContactName"] = "NewContactName";
rowCustomer.EndEdit();
}
使用BeginEdit 和 EndEdit 方法可以缓存对行的更改。此外,这种方式,在EndEdit前会阻止更新事件(如RowChanging, RowChanged, ColumnChanging, ColumnChanged)的发生。
3) 使用ItemArray属性。
同Item属性一样,使用ItemArray属性可以检索或修改行的内容,不同之处就在于Item属性一次只能处理一行,而ItemArray属性可以返回并接受对应列的一组项目。
object[] aCustomer={"ALFKI","NewCompanyName", "NewContactName", "NewPhoneNo"};
DataRow rowCustomer;
rowCustomer = ds.Tables["Customers"].Rows.Find("ALFKI");
rowCustomer.ItemArray = aCustomer;
如果希望使用ItemArray属性,但是又不希望修改行中每一列的值,可以使用null关键字。
object[] aCustomer = {null, "NewCompanyName",
"NewContactName", "NewPhoneNo"};
DataRow rowCustomer;
rowCustomer = ds.Tables["Customers"].Rows.Find("ALFKI");
rowCustomer.ItemArray = aCustomer;
6.5.3 处理DataRow的空值
DataRow对象有IsNull方法,可以查看列是否包含空值。同数据行对象的Item方法一样,IsNull方法接受列的名字、列在表中的索引或DataColumn对象。
DataRow rowCustomer;
rowCustomer = ds.Tables["Customers"].Rows.Find("ALFKI");
if (rowCustomer.IsNull("Phone"))
Console.WriteLine("It's Null");
else
Console.WriteLine("It's not Null");
希望给列赋空值时,不必使用所选编程语言中的关键字Null,可以使用DBNull类的value属性。
DataRow rowCustomer;
rowCustomer = ds.Tables["Customers"].Rows.Find("ALFKI");
rowCustomer["Phone"] = DBNull.Value;
6.5.4 删除DataRow
简单地调用DataRow的Delete方法就可以了。删除行并不是把它从DataTable中删掉,而是将行标志为挂起删除,以反映到数据库中。
6.5.6 清除DataRow
如果一定要从DataTable中清除行而不是将它标志为挂起删除,可以使用DataRowCollection类的Remove或RemoveAt方法。如果有对要删除的DataRow的引用,可以用前者;如果有索引编号,用后者。
此外,DataSet类和DataTable类分别包含了Clear方法,可以使用该方法从DataSet或DataTable中清除所有的DataRow对象而保留其结构。
6.5.7 使用DataRow.RowState属性
ADO.NET必须知道对DataRow所做修改的类型,这样以后才能成功地将更改提交给数据库。ADO.NET将此信息存储在DataRow中名为RowState的属性中,该属性用DataRowState枚举值通过查看属性可以知道行是否改动和修改类型(插入、删除或修改)。
DataRowState枚举值包括:
Unchanged 2 不包含任何挂起更改
Detached 1 该行不是DataTable的成员
Added 4 该行已被添加到DataTable中,却不在数据库中
Modified 16 该行包含挂起更改
Deleted 8 该行是一个挂起删除
6.5.8 检查DataRow中的挂起更改
依靠RowState属性可以浏览DataTable的内容并找到修改的行。
可以使用DataTable的Item属性来查看行中列的内容,Item属性可以接受DataRowVersion枚举中的第二个可选参数,DataRowVersion枚举包括:
Current 512 存储在列中的当前值
Original 256 存储在列中的原始值
Proposed 1024 列的建议值,只有当使用BeginEdit编辑行时有效
Default 1536 默认操作
注意:
Original值是从数据库中取得的值,不会改变。
删除行后无法访问Current,但可以访问Original
枚举中Default表示DataRow对象的Item属性中参数的默认值
如果不是正处于编辑行的过程中,那么调用Item并省略可选参数等价于将DataRowVersion.Current常数作为可选参数。如果是在编辑行的过程中,将得到列的Proposed值。
回顾Chap.6 处理DataSet对象(1)
6. 处理DataSet对象
6.1 DataSet的特性
DataSet对象其核心为数据的集合
特性:
1) 处理脱机数据
2) 浏览、排序、搜索和过滤
3) 处理分级数据
4) 缓存更改
5) Xml集成
6) 统一的功能
6.2 使用DataSet对象
1) DataColumn对象
属性:Name,Ordinal,DataType
2) DataRow对象
可以提供列的名称、列在DataTable中的序数位置、DataColumn对象三种方式访问DataRow对象中特定列的值,效率依次提高。
3) Constraint对象
6.3 校验DataSet中的数据
6.3.1 校验DataColumn的属性
设置DataColumn对应属性:
ü ReadOnly
ü AllowDBNull
ü MaxLength
ü Unique
6.3.2 DataTable对象的Constraints集合
ADO.NET中有两个类(UniqueConstraint和ForeignkeyConstraint)可以用于DataTable中定义约束。
DataTable提供一个Constraints属性可以用于添加、修改或查看DataTable上的约束。
ü UniqueConstraints
如果设置了DataColumn的Unique属性为true,也就在包含该列的DataTable里定义了一个约束,同时还将UniqueConstraints添加到DataTable对象的Constraints属性中。
设置unique属性的方式比创建一个UniqueConstraint容易,但在确定多列合并后的值是否唯一的时候,需要创建UniqueConstraint。
ü Primarykey
是UniqueConstraint的一种特殊类型,ADO.NET的DataRowCollection对象用Find方法来根据主键列的值查找DataTable的行。
可以使用DataTable对象的PrimaryKey属性设置和查看主键。
ü ForeignkeyConstraint
将外部约束添加到DataTable中。通常不必刻意去创建ForeignkeyConstraint,因为当在DataSet的两个DataTable对象之间创建一个DataRelation的过程时,也会创建一个ForeignkeyConstraint。
注意:在DataSet的列和表中定义的约束只能在该DataSet中有效。
6.3.3 用DataAdapter.Fill模式来检索模式信息
验证数据是需要时间的。许多方案都没有对DataSet设置验证属性,所以除非有明确的要求,DataAdapter对象的Fill方法在创建DataTable时并不对DataColumn对象设置验证属性,也不会将约束添加到DataTable对象的约束集合中。
当将列添加到DataTable时,可以用两种方法来通知DataAdapter在数据库中检索该模式信息:一种是通过将DataAdapter对象的MissingSchemaAction属性设置为AddWithKey来实现的,另一种是调用DataAdapter对象的FillSchema方法。
DataAdapter将试图为DataTable生成一个主键,这是相当糟糕的。如果表含有一个包括两个列的主键而使用的查询却不包括这些列,DataAdapter将不再使用DataTable中的这个主键。
DataAdapter也将设置新DataColumn对象的AutoIncrement属性。
6.4 编写代码创建DataTable对象
1) 创建DataTable对象
DataTable tbl=new DataTable(“TableName”);
2) 将DataTable添加到DataSet对象的Tables集合
DataTable tbl=new DataTable(“TableName”);
ds.Tables.Add(tbl);
或
ds.Tables.Add(“Customers”);
可以通过查看DataTable对象的DataSet属性来确定一个DataTable是否存在于DataSet中。
DataTable对象只能存在于至多一个DataSet对象中。如果希望将DataTable添加到多个DataSet中,就必须使用copy或clone方法。前者创建一个与原DataTable结构相同,并且包含相同行的新DataTable;后者创建一个与原DataTable结构相同,但没有包含任何行的新DataTable。
3) 为DataTable添加列
DataColumn col=tbl.Columns.Add(”CustomerID”);
4) 指定DataColumn的数据类型
可以使用DataColumn的DataType属性来设置或查看列将包含的数据类型。直到将数据添加到DataTable对象的Rows集合后,DataColumn对象的DataType属性才不是可读写的。
数据库的数据类型同DataColumn的数据类型不是一一映射的。
DataColumn的DataType属性默认为字符串,此外,DataColumn还包含一个构造函数,可以指定数据类型和所创建的新列的名称。同样,重载DataColumn集合对象的Add方法可以允许为新建DataTable对象和新建DataColumn对象的ColumnName和DataType属性赋值。
DataColumn col=tbl.Columns.Add(“OrderID”,typeof(int));
5) 添加主键
PrimaryKey属性包含一个DataColumn对象数组,所以不能只简单地将列的名称设置为主键。
tbl.PrimaryKey=new DataColumn[] {tbl.Columns[“OrderID”], tbl.Columns[“ProductID”]};
注意:为DataTable设置主键时,ADO.NET会自动将DataColumn对象或主键中引用到的对象的AllowDBNull属性设置为false。
6) 添加其他约束
DataTable的约束集合有一个重载的Add方法,可以添加新的主键、唯一键和外键约束。
用代码创建约束有两种方法:
第一种是直接创建一个新的约束对象并将它添加到DataTable的约束集合中。
tbl.Constraints.Add(New UniqueConstraint(…));
第二钟方法是使用约束集合对象的Add方法创建新约束并将它添加到集合中。
tbl.Constraints.Add(“ConstraintName”,ColumnInformation);
推荐使用第一种方法,因为容易理解。
tbl.Constraints.Add(new UniqueConstraint(tbl.Columns["CustomerID"]));
//or
tbl.Constraints.Add("UK_Customers", tbl.Columns["CustomerID"],
false);
//Add a unique key based on the OrderID and ProductID columns.
DataColumn[] cols = new DataColumn[] {tbl.Columns["OrderID"],
tbl.Columns["ProductID"]};
tbl.Constraints.Add(new UniqueConstraint(cols));
//or
tbl.Constraints.Add("UK_Order Details", cols, false);
//Add a foreign key constraint based on the OrderID column that
//requires a corresponding OrderID in the Orders table.
tbl.Constraints.Add(new ForeignKeyConstraint
(ds.Tables["Orders"].Columns["OrderID"],
tbl.Columns["OrderID"]));
//or
tbl.Constraints.Add("FK_Order Details_Orders",
ds.Tables["Orders"].Columns["OrderID"],
tbl.Columns["OrderID"]);
7) 处理自动增量列
ADO.NET通过DataColumn的3个属性来支持自动增量列,它们是:AutoIncrement、AutoIncrementSeed和AutoIncrementStep。
将DataColumn的AutoIncrement属性设置为true就可以为DataTable的新行生成自动增量值。
DataSet ds = new DataSet();
DataTable tbl = ds.Tables.Add("Orders");
DataColumn col = tbl.Columns.Add("OrderID", typeof(int));
col.AutoIncrement = true;
col.AutoIncrementSeed = -1;
col.AutoIncrementStep = -1;
col.ReadOnly = true;
依靠ADO.NET的自动增量功能,可在将行添加到DataTable时让ADO.NET对行进行计算,从而分页显示DataTable,而不用根据查询规则和行的排序来实现。
AutoIncrement的可为与不可为:
*可为:使用自动增量特性
*不可为:将生成的自动增量值提交给DB。该值仅仅是占位符。
*不可为:显示还未提交给数据库的新行自动增量值
*可为:将AutoIncrementSeed和AutoIncrementStep设置为-1,这样能确保生成的占位符不会在数据库中出现。即使在应用程序中显示该值,用户也不会误认为ADO.NET生成的自动增量值和数据库生成的自动增量值相同。
8) 添加基于表达式的列
ADO.NET允许创建基于表达式的DataColumn对象。可以将DataColumn对象的Expression属性设置为一个表达式,而用不着在查询中包含表达式。当查看列的内容时,ADO.NET就会计算表达式并返回结果。
tbl.Columns.Add("Quantity", typeof(int));
tbl.Columns.Add("UnitPrice", typeof(Decimal));
tbl.Columns.Add("ItemTotal", typeof(Decimal),"Quantity * UnitPrice");