在ASP.NET 2.0中操作数据之四十七:用SqlDataSource控件插入、更新、删除数据


当前第2页 返回上一页


图8:选中“生成INSERT、UPDATE和DELETE命令”选项

  当查询返回的那些列包含主键列(有时几个列都是主键列)时,才能启用“生成INSERT、UPDATE和DELETE命令”选项。当选择了“生成INSERT、UPDATE和DELETE命令”选项后,才能选择“使用开放式并发”选项。当选择该选项后,就将在UPDATE和DELETE命令里增加WHERE字句,以提供开放式并发控制。现在先不忙选择“使用开放式并发”选项,我们将在后面的教程里讨论如何使SqlDataSource控件实现开放式并发。

  当选择“生成INSERT、UPDATE和DELETE命令”选项后,点“OK”回到“设置选择命令”界面,再点下一步,点完成。完成向导后,Visual Studio将会为DetailsView控件增加ProductID, ProductName和UnitPrice三个绑定列(BoundFields),和一个Discontinued单选框列(CheckBoxField )。在DetailsView控件的智能标签里选择分页项,并清空DetailsView的宽、高属性。

  我们注意到智能标签里还包括插入、编辑、删除选项可用,这是因为SqlDataSource控件的InsertCommand, UpdateCommand和DeleteCommand属性同样被赋值了。就像如下代码所示:

<asp:DetailsView ID="ManageProducts" runat="server" AllowPaging="True"
AutoGenerateRows="False" DataKeyNames="ProductID"
DataSourceID="ManageProductsDataSource" EnableViewState="False">
<Fields>
 <asp:BoundField DataField="ProductID" HeaderText="ProductID"
  InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
 <asp:BoundField DataField="ProductName" HeaderText="ProductName"
  SortExpression="ProductName" />
 <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
  SortExpression="UnitPrice" />
 <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
  SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>

<asp:SqlDataSource ID="ManageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
DeleteCommand=
 "DELETE FROM [Products] WHERE [ProductID] = @ProductID"
InsertCommand=
 "INSERT INTO [Products] ([ProductName], [UnitPrice], [Discontinued])
  VALUES (@ProductName, @UnitPrice, @Discontinued)"
SelectCommand=
 "SELECT [ProductID], [ProductName], [UnitPrice], [Discontinued]
  FROM [Products]"
UpdateCommand=
 "UPDATE [Products] SET [ProductName] = @ProductName,
  [UnitPrice] = @UnitPrice, [Discontinued] = @Discontinued
  WHERE [ProductID] = @ProductID">
<DeleteParameters>
 <asp:Parameter Name="ProductID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
 <asp:Parameter Name="ProductName" Type="String" />
 <asp:Parameter Name="UnitPrice" Type="Decimal" />
 <asp:Parameter Name="Discontinued" Type="Boolean" />
 <asp:Parameter Name="ProductID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
 <asp:Parameter Name="ProductName" Type="String" />
 <asp:Parameter Name="UnitPrice" Type="Decimal" />
 <asp:Parameter Name="Discontinued" Type="Boolean" />
</InsertParameters>
</asp:SqlDataSource>

  注意:SqlDataSourc控件是如何自动的为InsertCommand,UpdateCommand和DeleteCommand属性赋值的。InsertCommand和UpdateCommand属性里涉及到的列取决于SELECT命令里的列,换句话说,并不是表Products的所有列都出现在InsertCommand和UpdateCommand属性里。在InsertCommand和UpdateCommand属性里只能使用SelectCommand返回的那些列(列ProductID除外,因为它是一个IDENTITY列,IDENTITY列的值在编辑的时候不允许改变,而且新插入一条记录时,自动对IDENTITY列赋值)。另外在InsertCommand, UpdateCommand和 DeleteCommand属性里出现的每个参数,在<DeleteParameters>、<UpdateParameters>、<InsertParameters>标记里都有对应的参数。

  再转向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种生成代码的方法。

  祝编程快乐!

作者简介

  本系列教程作者 Scott Mitchell,著有六本ASP/ASP.NET方面的书,是4GuysFromRolla.com的创始人,自1998年以来一直应用 微软Web技术。大家可以点击查看全部教程《[翻译]Scott Mitchell 的ASP.NET 2.0数据教程》,希望对大家的学习ASP.NET有所帮助。

更多SQL内容来自木庄网络博客


打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...

    正在狠努力加载,请稍候...