再转向DetailsView的数据修改属性,在智能标签里启用插入、编辑、删除功能。这样会添加一个CommandField,并将ShowInsertButton、ShowEditButton和 ShowDeleteButton属性设置为true。
在浏览器访问该页,注意到编辑、删除、新建按钮出现在DetailsView控件中,点“编辑”按钮,DetailsView控件将进入编辑模式,那些ReadOnly属性设置为false(默认)的绑定列将变成一个文本框,而CheckBoxField将变成单选框。
图9:DetailsView控件的默认编辑界面
类似的,你可以将当前选定行删除,或向系统增加新产品记录。由于InsertCommand语句里只包含ProductName, UnitPrice和Discontinued三列,当完成新增记录时,其它列要么为NULL要么使用数据库默认值。和ObjectDataSource控件一样,假设数据库表中存在这样的列,其值不允许为NULL,且未设置默认值,如果在
InsertCommand命令里未包含该列的话,当你试图执行该INSERT语句的时候将出错。
注意:DetailsView控件的默认插入和编辑界面不能实现用户定制和确认功能,为了能实现用户定制及添加确认控件,我们需要将绑定列(BoundFields)转换成模板列(TemplateFields)。获得更多这方面的信息,请参阅前面的教程Adding Validation Controls to the Editing以及Customizing the Data Modification Interface 。同时谨记,当进行更新和删除操作时,DetailsView控件将使用当前产品的DataKey值。如果编辑或删除失败话,检查DataKeyNames属性是否设置正确。
自动生成SQL语句的局限性
只有当选择从表返回列时,才能选用“自动生成INSERT, UPDATE和DELETE命令”选项,从而自动生成SQL语句。然而,对更复杂的查询来说,我们将像第一步那样手动书写INSERT, UPDATE和DELETE语句。 一般来说,我们在SQL SELECT命令里使用JOINs将不同表的不同表的数据连接起来(打个比方,我们在显示产品信息的同时希望显示供应商名字CategoryName,但是Products表里没有CategoryName列,那就只有调动表Categories的CategoryName列)。同时我们对“主”表执行编辑、更新和删除操作(具体到本例,“主”表就是Products表)
对这种需要手工输入的比较复杂的查询,按以下步骤来做可以省时一些。首先,创建一个从表Products返回数据的SqlDataSource控件,在其“设置数据源向导”里选择“指定来自表或视图的列”模式来自动地生成INSERT, UPDATE和DELETE语句。完成设置后在属性窗口打开SelectQuery属性(或者直接在“设置数据源向导”里选用“自定义SQL语句或存储过程”模式),最后在SELECT命令里添加JOIN字句。这个方法既有自动生成SQL语句省时的优点,又可以自定义SELECT语句。
另一个局限性在于,自动生成的INSERT和UPDAT命令里包含的是那些SELECT命令返回的列,而我们实际需要插入或更新的列可能比这些列多也可能比这些列少。比如在第2步中,如果我们要将UnitPrice设置为只读,那么它就不应该UpdateCommand语句里面, 或者我们希望在新增记录时对QuantityPerUnit赋值为“TODO”,但在GridView控件里并没有显示QuantityPerUnit列。
对这种情况,我们需要手工输入代码。要么直接声明代码,要么在“设置数据源向导”里选择“指定SQL语句或存储过程”模式,要么通过属性窗口设置。
注意:当新增一个参数时,如果在数据Web控件里没有与该参数对应的列话,我们应通过其他方法对该参数赋值:在InsertCommand和UpdateCommand语句里通过硬编码赋值;通过预定义源(比如查询字符串、session状态,页面上的控件等)传递参数;通过编程对参数赋值。
总结:
要使数据Web控件能启用其内建的插入、编辑、删除功能,它绑定的数据源控件首先要提供这些功能函数。对SqlDataSource来说,就是其InsertCommand, UpdateCommand和DeleteCommand属性必须包含INSERT,UPDATE和DELETE语句。在本节教程我们探讨了手工和自动2种生成代码的方法。
祝编程快乐!
作者简介