System.Data.DataRelation学习笔记

本文深入探讨了DataRelation对象的功能,包括使与当前记录相关的记录可用,以及如何通过删除父记录来强制引用完整性的删除相关子记录。同时展示了如何通过代码实现这些功能。

DataRelation 对象执行两种功能:

  • 它可使与正使用的记录相关的记录可用。如果在父记录 (GetChildRows) 中,则它提供子记录;如果正使用子记录 (GetParentRow),则它提供父记录。

  • 它可强制约束的引用完整性,如删除父记录时删除相关的子记录。

以下代码为此两种功能的演示:

/// <summary> /// /// </summary> [TestFixture] public class DataRelationStudy { [Test] public void Execute() { DataSet dataSet = new DataSet(); dataSet.Tables.Add(CreateCustomerTb()); dataSet.Tables.Add(CreateOrderTb()); DataRelation relation = dataSet.Relations.Add("relation", dataSet.Tables["customer"].Columns["ID"], dataSet.Tables["order"].Columns["CustomerID"]); DisplayByChildRows(dataSet, relation); DisplayByParentRow(dataSet, relation); dataSet.Tables["order"].WriteXml(Console.Out); dataSet.Tables["customer"].Rows.RemoveAt(0); Console.WriteLine("删除customer表中的张三后"); dataSet.Tables["order"].WriteXml(Console.Out); } private void DisplayByParentRow(DataSet dataSet, DataRelation relation) { Console.WriteLine("通过父行来显示数据"); foreach (DataRow row in dataSet.Tables["order"].Rows) { Console.WriteLine(String.Format("OrderDate:{0} CustomerName:{1}",row["OrderDate"],row.GetParentRow(relation)["Name"])); } } private void DisplayByChildRows(DataSet dataSet, DataRelation relation) { Console.WriteLine("通过子行来显示数据"); foreach (DataRow row in dataSet.Tables["customer"].Rows) { foreach (DataRow childRow in row.GetChildRows(relation)) { Console.Write(String.Format("Name:{0} OrderDate:{1}",row["name"],childRow["OrderDate"])); } Console.WriteLine(); } } private DataTable CreateOrderTb() { DataTable result = new DataTable("order"); result.Columns.Add("CustomerID", typeof(Int32)); result.Columns.Add("OrderDate", typeof(DateTime)); DataRow row1 = result.NewRow(); row1["CustomerID"] = 3; row1["OrderDate"] = DateTime.Now; DataRow row2 = result.NewRow(); row2["CustomerID"] = 4; row2["OrderDate"] = DateTime.Now.AddDays(1); DataRow row3 = result.NewRow(); row3["CustomerID"] = 3; row3["OrderDate"] = DateTime.Now.AddDays(-1); ; result.Rows.Add(row1); result.Rows.Add(row2); result.Rows.Add(row3); result.AcceptChanges(); return result; } private DataTable CreateCustomerTb() { DataTable result = new DataTable("customer"); result.Columns.Add("ID", typeof (Int32)); result.Columns.Add("Name", typeof (String)); DataRow row1 = result.NewRow(); row1["ID"] = 3; row1["Name"] = "张三"; DataRow row2 = result.NewRow(); row2["ID"] = 4; row2["Name"] = "李四"; DataRow row3 = result.NewRow(); row3["ID"] = 3; row3["Name"] = "王五"; result.Rows.Add(row1); result.Rows.Add(row2); result.Rows.Add(row3); result.AcceptChanges(); return result; } }

代码输出结果:

通过子行来显示数据

Name:张三 OrderDate:2010-8-7 19:53:20Name:张三 OrderDate:2010-8-6 19:53:20

Name:李四 OrderDate:2010-8-8 19:53:20

通过父行来显示数据

OrderDate:2010-8-7 19:53:20 CustomerName:张三

OrderDate:2010-8-8 19:53:20 CustomerName:李四

OrderDate:2010-8-6 19:53:20 CustomerName:张三

<NewDataSet>

<order>

<CustomerID>3</CustomerID>

<OrderDate>2010-08-07T19:53:20.65625+08:00</OrderDate>

</order>

<order>

<CustomerID>4</CustomerID>

<OrderDate>2010-08-08T19:53:20.65625+08:00</OrderDate>

</order>

<order>

<CustomerID>3</CustomerID>

<OrderDate>2010-08-06T19:53:20.65625+08:00</OrderDate>

</order>

</NewDataSet>删除customer表中的张三后

<NewDataSet>

<order>

<CustomerID>4</CustomerID>

<OrderDate>2010-08-08T19:53:20.65625+08:00</OrderDate>

</order>

</NewDataSet>

此外它还有唯一约束的功能,它保证父表中的列不包含重复内容,也这也是为什么GetParentRow而不是GetParentRows了,如果把这段代码插入到CreateCustomerTb()方法中

DataRow row3 = result.NewRow(); row3["ID"] = 3; row3["Name"] = "王五"; result.Rows.Add(row3);

则会报“System.ArgumentException : 这些列当前不具有唯一值“的异常

再来看:外键约束,可用来维护数据集中的父表和子表之间的引用完整性。

比如这时把CreateOrderTb方法中的row3["CustomerID"] = 3; 改为row3["CustomerID"] = 5,程序报如下异常:

“System.ArgumentException : 不能启用此约束,因为不是所有的值都具有相应的父值”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值