中国的四个直辖市:8.4.2 使用多个表和关系
来源:百度文库 编辑:偶看新闻 时间:2024/05/02 17:44:47
8.4.2 使用多个表和关系
下一个示例显示了DataSet更高级的应用,包括提供非连接的数据,使用表间的关系。该示例演示了如何从Northwind数据库的Categories表和Products表中检索数据,如何在两表间创建关系从而方便地从类别记录导航到它所属的子产品并创建报表。
第一步是初始化ADO.NET对象并声明两个SQL查询(分别读取Categories和Products表)语句,如下所示:
接着,代码执行这两个查询,往DataSet中添加两个表。注意,开始时连接被显式地打开并在两个操作执行后关闭,这尽可能地保证了最佳的性能。在这个示例中,两个表使用了同一个DataAdapter。这样的技术完全合理,且在这样的场景中很有效,因为不需要重用DataAdapter去更新数据源。不过,如果既要用DataAdapter查询数据又要用它提交更新,就应该避免这样的做法。相反,应该为每个表创建一个独立的DataAdapter,这样每个DataAdapter都为对应的表提供适当的插入、更新和删除命令。
现在你得到了一个有两张表的DataSet。在Northwind数据库里,这两张表通过CategoryID字段关联。该字段是Categories表的主键同时也是Products表的外键。遗憾的是,ADO.NET没有提供任何从数据源中读取关系并自动应用到DataSet的方法。我们需要手工创建一个DataRelation来表示关系。
关系通过定义一个DataRelation对象并把它加入到DataSet.Relations集合来创建。创建关系时,需要提供构造函数的3个参数:关系的名称、父表中作为主键的DataColumn、子表中作为外键的DataColumn。
下面是示例需要的代码:
得到全部数据后,就可以循环遍历Categories表的记录并把每个类别的名字添加到HTML字符串里:这部分很有意思。在这一段代码中,对于当前类别,可以调用DataRow.GetChildRows()方法访问相关产品的记录。该方法在链接的DataTable中查找内存中的数据以查找匹配的记录。得到产品记录数组后,就可以通过内嵌的循环查看它们了。这样的代码远比从独立对象查找相关的信息简单,也远比传统的基于连接来执行多次查询要简单。
下面的代码片段演示了这个方法,读取子记录并完成外部foreach循环:
最后一步是在页面上显示HTML字符串的内容:示例的所有代码都完整了。现在运行页面,你会看到如图8-5所示的输出。
提示
ADO.NET新手常问的一个问题是,什么时候使用JOIN查询,又在什么时候使用DataRelation对象?最重要的是看是否要更新获得的数据。如果答案是"是",那么使用独立的表和DataRelation通常能够提供最佳的灵活性;如果不需要更新数据,两者都可使用,不过JOIN查询效率更高一些,因为它只需在网络间往返一次,而使用DataRelation的实现需要往返两次以填充两个独立的表。
图8-5 每个类别中的产品列表引用完整性
在DateSet中添加了一个关系后,就会受到引用完整性的约束。例如,你不能删除一个有连接子行的父记录,同时你也不能创建一个引用不存在的父记录的子记录。这样当DataSet只包含部分数据时会产生一些问题。例如,你有客户订单的完整列表,但只有部分客户的信息,结果是部分订单指向了那些不存在的客户,其实只是这些客户不在你的DataSet中。解决这个问题的一个办法是创建一种没有这类约束的关系。使用DataRelation的一个接受createConstraints参数的构造函数就可以做到这一点,如下面的代码:
另一个办法是在添加关系前将DataSet.EnforceConstraints属性设为假,从而禁用所有类型的约束检查(包括唯一值检查)。