图6:添加一个附带Brochure和Image文件的测试类
图7:添加测试类后,显示在GridView控件里
在Visual Studio里刷新解决资源管理器,你会在文件夹~/Brochures里看到Test.pdf文件(见图8)
下一步,点击Test类的Delete链接,页面回传,引发CategoriesBLL的DeleteCategory 方法,该方法又调用DAL层的Delete方法,向数据库发送适当的DELETE命令。最后数据重新绑定到GridView控件,Test类将不再显示出来。
虽然已经成功地将Test类从Categories表删除,但存储在文件系统的对应小册子仍旧存在,刷新解决资源管理器,你将发现Test.pdf依然放在~/Brochures文件夹里。
图8:Test.pdf文件并没有从文件系统删除
第5步:删除残存的Brochure文件
未将二进制数据存储进数据库时面临的一个问题便是:当删除一条数据库记录时,我们需要另外采取步骤来删除该记录对应的二进制数据文件。当执行delete命令时,会发生一些事前事件和事后事件(pre- and post-action events),我们需要创建对应的事件处理器。在Categories表的记录被删除之前,我们需要确定对应PDF文件的路径,但在删除记录之前我们不会删除其对应的PDF文件,以防发生异常或记录最终未被删除的情况。
从事件发生的时间先后顺序来看,GridView控件的RowDeleting事件在调用ObjectDataSource控件的delete命令前发生;而RowDeleted事件在调用ObjectDataSource控件的delete命令之后再发生。创建这2个事件处理器,代码如下:
// A page variable to "remember" the deleted category's BrochurePath value string deletedCategorysPdfPath = null; protected void Categories_RowDeleting(object sender, GridViewDeleteEventArgs e) { // Determine the PDF path for the category being deleted... int categoryID = Convert.ToInt32(e.Keys["CategoryID"]); CategoriesBLL categoryAPI = new CategoriesBLL(); Northwind.CategoriesDataTable categories = categoryAPI.GetCategoryByCategoryID(categoryID); Northwind.CategoriesRow category = categories[0]; if (category.IsBrochurePathNull()) deletedCategorysPdfPath = null; else deletedCategorysPdfPath = category.BrochurePath; } protected void Categories_RowDeleted(object sender, GridViewDeletedEventArgs e) { // Delete the brochure file if there were no problems deleting the record if (e.Exception == null) { // Is there a file to delete? if (deletedCategorysPdfPath != null) { System.IO.File.Delete(Server.MapPath(deletedCategorysPdfPath)); } } }
在RowDeleting事件处理器里,从GridView控件的DataKeys集合里获取被删记录的CategoryID值,而在这里,我们通过e.Keys来访问DataKeys集合。接着,调用类CategoriesBLL的GetCategoryByCategoryID(categoryID)方法来返回被删记录的信息,若返回的BrochurePath值不为NULL,那么将其赋值给页面参数deletedCategorysPdfPath,再在RowDeleted事件处理器里删除文件。
注意:在RowDeleting事件处理器里,我们没有返回被删记录的BrochurePath信息,而是将BrochurePath添加到GridView的DataKeyNames属性,再通过访问e.Keys来获取该记录的值。这样做虽然稍微增大了GridView的视图状态,但减少了必要的代码,也省了一步访问数据库。
调用ObjectDataSource控件的delete命令后,紧接着发生GridView控件的RowDeleted事件,如果删除过程没有异常且deletedCategorysPdfPath值不为空,那就将对应的PDF文件从文件系统删除。我们注意到,代码没有删除类的picture,那是因为picture数据是直接存储在数据库里的,当删除记录时就一起删除了。
添加完上述2个事件处理器后,再次测试删除。当删除某个类时,其对应的PDF文件也删除了。
下面我们深入研究添加更新功能以应对类的brochure和picture.第6步探讨更新brochure信息的技术,第7章探讨更新picture。
第6步:更新类的Brochure
就像在教程16《概述插入、更新和删除数据》里探讨的一样,如果GridView的数据源控件支持编辑,那么我们就可以启用GridView控件的编辑功能。当前,名为CategoriesDataSource的ObjectDataSource控件并不支持编辑,那让我们添加吧。