集合和关系
表达式中的嵌入集合函数能帮助你建立一个表现更复杂逻辑的表达式。如果要建立一个列计算跨多个行的值怎么办?最好加入集合函数。
假定在一个数据集中有类似SQL Server的Northwind数据库中的订单到订单细节的关系结构,那么用包含集合函数的表达式建立列就很直接。下面的代码演示了怎样建立一个包含结构的数据集,在该数据集中订单位于父数据表而订单细节位于子数据表。这些数据表对象通过一个叫Orders2OrderDetails的数据关系彼此关联。
请注意代码是怎样建立表达式列并添加到Order 数据表的。第一个表达式建立一个表现每个订单的详细信息汇总的列。特别的是OrderTotal数据列有一个表达式用于汇总OrderDetail数据表的基于表达式的ExtendedPrice数据列。你能发现,可以跨越数据关系使用集合函数并将它用在另一个基于表达式的列上。
ADO.NET中还有其它的集合函数,包括Sum、Avg、Max、Min、StDev、Var和Count。下面的代码演示了怎样使用Avg函数得到订单详细数量的平均值。关键在于使用父(parent)和子(child)关键字通过数据关系连接数据:
oDs.Tables["Order"].Columns.Add("AvgQuantity", typeof(decimal), Avg(Child(Order2OrderDetail).Quantity)"); |
Child函数接受数据关系名来获取子行集合。该参数是可选的,只有在源数据表中的子关系多于一个时才需要。因此,如果数据表只有一个子表,语法可以简化:
oDs.Tables["Order"].Columns.Add("AvgQuantity", typeof(decimal), Avg(Child.Quantity)"); |
向下滚动和计算 Parent函数与Child函数工作类似,只是它沿关系链上行到达父数据表。在ADO.NET代码中这两个函数帮助建立一个假的GROUP BY函数性。
这些关键字的另一个操作是上滚或下滚从一个数据表到另一个数据表不变的值。经常有人问我怎样将一个父数据表和子数据表连接成一个数据表,这样才能在一个DataGrid控件中显示。使用父关键字可以将字段下滚到子数据表,接着只将该子数据表绑定到DataGrid控件。例如,需要显示OrderDetail数据表中每一行的订单日期,可以添加一个使用父关键字的数据列:
oDs.Tables["OrderDetail"].Columns.Add("OrderDate", typeof(string), "Parent.OrderDate"); |
这个特征使得不需要作任何计算就可以上滚和下滚字段。使用Child关键字可以从父表中下滚字段并绑定到DataGrid控件。执行该操作后你得到了一个两位小数的行集合,与从SQL语句中得到的一样。要记住,如果打算使用单个行集合中的数据,最好返回单个行集合到数据表。但是,如果你想在数据集中使用关系结构,Parent关键字给了你显示数据的灵活性。
另一个值得一看的特征是数据表的Compute函数,该函数使用给定了过虑条件的当前数据表上的集合函数来计算。例如,能给数据表加一列用于计算订单总价大于999的订单总数量。
在下例所示的Compute函数的第一个参数中,执行了一个集合函数计算符合条件的所有OrderTotal值:
//显示订单价格大于999的订单数量 int iCnt = (int)oDs.Tables["Order"].Compute("Count(OrderTotal)", "OrderTotal >= 1000"); lblTest.Text = iCnt.ToString() + " orders are at least $1000"; |
在第二个参数中指定了过滤器,将集合函数限定为只包含符合条件的行。代码计算OrderTotal大于或等于1000的行。这是一个在数据表中快速执行计算的强大工具,尤其是能使用过虑。例如,你能很容易地查找出订X货物的顾客数量和订Y货物的顾客数量,而不需要循环查询数据库。
注意绑定到表达式的数据列对象不能手动更新。绑定到表达式的列不会被覆盖,除非表达式被删除。当然,这些数据也不会与数据库或XML文件中作为数据源的列相对应。因此,如果你想将数据保存到数据库中时,要记得表达式不能保存进数据库。
上文讨论了SQL和ADO.NET中的表达式,演示了表达式所提供的广泛的函数功能,你能在应用程序中使用它们生成和添加数据。
查看本文来源