1.通过一个SQL查询——我们可以向数据库发出一个额外的查询来为某个特定的类别计算统计信息。SQL包含一系列的聚合函数,并由GROUP BY子句指定应该根据什么数据来进行统计。下面的SQL查询将会返回我们所需要的信息:
SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock), SUM(UnitsOnOrder) FROM Products WHERE CategoryID = categoryID GROUP BY CategoryID
当然,你也可能不喜欢直接在SummaryDataInFooter.aspx页面中直接执行这个查询,而是希望在ProductsTableAdapter 和ProductsBLL 中创建一个方法来干这个事情。
2.由于这些信息已经添加到GridView中了,所以可以直接计算——就像在“基于数据的自定义格式化”中讨论的那样,在GridView的数据绑定之后,GridView的RowDataBound事件处理方法会在添加每一行数据时被执行一次。为这个事件创建了事件处理方法之后,我们就可以保持一个累积的合计值了。在最后一行数据被绑定到DataGrid上之后,我们就有了一个合计值以及需要计算平均值的信息了。
一般来说,我还是喜欢第二种方法的,因为它节省了一次到数据库的往返,而且要达到这个效果还需要在数据访问层和业务逻辑层中实现统计功能,不过话说回来了,其实两种办法都行的。在这本教程中,我们还是使用第二个办法吧,并使用RowDataBound事件处理方法来记录这个累积合计。
给GridView新建一个RowDataBound事件处理方法,你可以在设计器中选择GridView,然后在属性窗口中点击那个带闪电符号的图标,找到RowDataBound事件并双击它就可以了。这样就会在SummaryDataInFooter.aspx页面的后置代码类中添加一个新的名为ProductsInCategory_RowDataBound的事件处理方法了。
protected void ProductsInCategory_RowDataBound (object sender, GridViewRowEventArgs e) { }
为了可以维护一个累积合计,我们需要在这个事件处理方法的外面定义一些变量。创建以下4个页面级的变量:
·_totalUnitPrice,类型为decimal
·_totalNonNullUnitPriceCount,类型为int
·_totalUnitsInStock,类型为int
·_totalUnitsOnOrder,类型为int
然后,在RowDataBound事件处理方法中写一些代码,使每一个数据行都可以增加这些变量的值。
// Class-scope, running total variables... decimal _totalUnitPrice = 0m; int _totalNonNullUnitPriceCount = 0; int _totalUnitsInStock = 0; int _totalUnitsOnOrder = 0; protected void ProductsInCategory_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { // Reference the ProductsRow via the e.Row.DataItem property Northwind.ProductsRow product = (Northwind.ProductsRow) ((System.Data.DataRowView)e.Row.DataItem).Row; // Increment the running totals (if they are not NULL!) if (!product.IsUnitPriceNull()) { _totalUnitPrice += product.UnitPrice; _totalNonNullUnitPriceCount++; } if (!product.IsUnitsInStockNull()) _totalUnitsInStock += product.UnitsInStock; if (!product.IsUnitsOnOrderNull()) _totalUnitsOnOrder += product.UnitsOnOrder; } }
在RowDataBound事件处理方法中,我们首先应该确保我们正在操作一个DataRow。一旦确定了是这么回事,e.Row中那个刚刚绑定到GridViewRow对象的Northwind.ProductsRow实例就可以赋值给product变量了。接着,累积合计就被当前产品的相关值(当然了,我们还是应该要确保它们不会含有一个数据库NULL值)增加了。我们同时记录了累积的UnitPrice合计以及非空UnitPrice记录的条数,因为平均价格是这两个数的商。
第四步:在页脚中显示统计数据
计算了统计数据之后,最后一个步骤就是在GridView的页脚上显示它了。同样,这个任务也可以通过RowDataBound事件处理方法来完成。回忆一下RowDataBound事件处理方法,它会在每一行绑定到GridView的时候被触发,页脚行也不例外。因此,我们可以扩展我们的事件处理方法,让它可以通过如下的代码来在页脚行中显示数据: