第二,INNER JOIN 语句造成一些不必要的数据移动。我们无法解决第二个问题,可是某些 ADO.NET 代码却有助于解决第一个问题。因此,我们仍然有机会提高整个解决方案的可行性和有效性。
具体思路如下:首先执行 SQL 查询,将返回结果集保存到一个 DataTable 对象中;然后把 DataTable 中的数据分散到 3 个不同却又相关的 DataTable 对象中。最终输出的结果与分别查询诸表没什么区别,可它却节省了定义和设置“可串行”事务的开销,同时也避免了从数据库下载多余记录;美中不足是每一行都可能包含少量冗余信息。
何时可以采用本方案呢?我发现,当客户端需要借助 group-by 函数及各种过滤器来组建一个复杂的“主从复合结构”(master/detail) 视图时,本方案是一个不错的选择。顺便提一句,此时采用多个不同而相关的表是非常有效的,ADO.NET 也为此提供了不少优化特性。
我们来讨论具体操作。以下代码示范了它的主要流程:
Function SplitData(ByVal ds As DataSet) As DataSet Dim _dataset As New DataSet()
' Make a full worker copy of the DataSet _dataset = ds.Copy()
CreateCustomers(_dataset, ds) CreateEmployees(_dataset, ds)
' Remove columns from Orders(companyname [2] and lastname [4]) _dataset.Tables("Orders").Columns.RemoveAt(1) _dataset.Tables("Orders").Columns.RemoveAt(3)
Return _dataset End Function
代码首先完整地复制了 DataSet 对象(ds),以它作为新 DataSet 对象(_dataset) 中的Orders 表。接下来,代码又在新 DataSet 对象中动态添加了 customers 表和 employees 表。最后,它又从新 DataSet 对象的 Orders 表中删除了其它两个子表所包含的列。下图显示了新 DataSet 对象中 customers 表的内容。瞧,它只留下了 Orders 表中 (所有) 订单的客户 ID 和公司名两列。由于这两个表都有 customerid 列,故它们仍然可以建立关系。

图 3 . 根据第一次查询的返回结果新生成的 Customers 表
下面来简单谈谈用于创建和填充 customers 表与 employees 表所必需的代码。
一开始,你必须调用 clone 方法克隆原先的订单表以创建一个新的 DataTable 对象。与Copy 方法不同,Clone 方法仅仅复制元数据(metadata)。由于 DataTable 接口不允许克隆单个列,所以本方法是生成对等表的最简单途径。然而,这样生成的表将包含某些多余列,我们必须删除之。
只要分析第一个 DataSet 对象的结构,你就会发现 customerid 列和 companyname 列正是返回结果集的第一列和第二列。
Dim _customers As DataTable = orig.Tables("Orders").Clone() _customers.TableName = "Customers"
' Remove unneeded columns Dim i As Integer For i = 2 To _customers.Columns.Count - 1 _customers.Columns.RemoveAt(2) Next
建立表结构之后,还得载入数据。然而,在 Orders 表中可能多次出现同一个提交者。此外,你必须对源 DataSet 对象中的数据加以过滤。好在 Orders 表已经根据 customerid 列进行排序,所以你只要循环遍历所有行,从中选出符合条件者即可。
Dim row As DataRow Dim customerKey As String = "" For Each row In _dataset.Tables("Orders").Rows ' Already sorted by CustomerID If customerKey <> row("customerid") Then ' select distinct _customers.ImportRow(row) customerKey = row("customerid") End If Next
' Add to the DataSet _dataset.Tables.Add(_customers)
ImportRow 是从数据库导出指定行到新表的最快途径。通常,ImportRow 方法会根据模式 (schema) 的要求来挑选被导出的列。
原则上,employeess 表的创建和 customers 表的创建大体相同。当然了,你应该删除的列有所不同。从 Orders 表的结构来分析,我们必须保留第 3 列与第 4 列。下列代码首先删除第1列和第2列,然后用一个循环解决其它列。
上一页 [1] [2] [3] [4] [5] [6] 下一页
|