图 5: 为CategoriesaDataSource增加一个新列
这样会添加一个名为Column1的列,你可以很方便的修改它的名字.将它重命名为NumberOfProducts.然后我们需要配置这列的属性.点这个列,来到属性窗口.将DataType从System.String修改为System.Int32.将ReadOnly属性设为True.见图6.
图 6: 设置新列的属性
现在CategoriesDataTable里已经包含了NumberOfProducts列,但它的值还没有设置.我们可以修改GetCategories()方法,当每次获取category信息的时候返回它的信息.在这里由于只是本章用到了这个数据,我们来创建一个新的名为GetCategoriesAndNumberOfProducts().右键点CategoriesTableAdapter,选择New Query.会出现TableAdapter Query配置向导.选择SQL statement.
图 7: 选择SQL Statement
图 8: SQL Statement 返回行数
下一步需要我们写sql语句.下面的语句返回每个category的CategoryID,CategoryName,Description和相关product的总数:
SELECT CategoryID, CategoryName, Description, (SELECT COUNT(*) FROM Products p WHERE p.CategoryID = c.CategoryID) as NumberOfProducts FROM Categories c
图 9: 使用的sql语句
注意计算product总数的子查询的别名为NumberOfProducts.它和CategoriesDataTable的NumberOfProducts列关联.最后一步是写方法的名字.分别为Fill a DataTable和Return a DataTable命名为FillWithNumberOfProducts和GetCategoriesAndNumberOfProducts.
图 10: 为新的TableAdapter的方法命名
现在DAL已经修改完了.由于我们所有展现层,BLL,DAL是逐层调用,所以我们需要在CategoriesBLL类的添加相应的GetCategoriesAndNumberOfProducts方法.
[System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select, false)] public Northwind.CategoriesDataTable GetCategoriesAndNumberOfProducts() { return Adapter.GetCategoriesAndNumberOfProducts(); }
完成DAL和BLL后,我们来将数据绑定到Categories Repeater.如果在"在ItemDataBound Event Handler里获取Products总数"那部分里你已经为Repeater创建了ObjectDataSource,删掉它,然后去掉Repeater的DataSourceID属性,同样去掉ItemDataBound事件.Repeater现在回到了初始状态,添加一个名为CategoriesDataSource的ObjectDataSource.使用CategoriesBLL类的GetCategoriesAndNumberOfProducts()方法来配置它.见图11.
图 11: 配置ObjectDataSource
然后修改ItemTemplate,使用数据绑定语法来将CategoryName和NumberOfProducts字段绑定到LinkButton的Text属性.完整的标记语言如下:
<asp:Repeater runat="server" DataSourceID="CategoriesDataSource"> <HeaderTemplate> <ul> </HeaderTemplate> <ItemTemplate> <li><asp:LinkButton runat="server" Text='<%# String.Format("{0} ({1:N0})", _ Eval("CategoryName"), Eval("NumberOfProducts")) %>' /> </li> </ItemTemplate> <FooterTemplate> </ul> </FooterTemplate> </asp:Repeater> <asp:ObjectDataSource runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategoriesAndNumberOfProducts" TypeName="CategoriesBLL"> </asp:ObjectDataSource>
使用这种方法的页面看起来和前面一种方法一样(见图4).
第三步: 显示选中的Category关联的Products
现在category和product总数的部分已经完成.Repeater将每个category显示为LinkButton,当点击时产生postback,这时我们需要将那些关联的product在CategoryProducts DataList里显示出来.