ObjectDataSource包含了对应它关联的方法的每一个输入参数的parameter,就像当ObjectDataSource被配置为调用预期一个输入参数的查询方法(例如GetProductsByCategoryID(categoryID))时出现的SelectParameters一栏。正如我们马上即将看到的,这些DeleteParameters、UpdateParameters和InsertParameters的值在调用ObjectDataSource的Insert()、Update()或Delete()方法之前自动地通过GridView、DetailsView和FormView被设置。必要时这些值也可以通过编程设置,这在以后的章节里讨论。
使用数据源配置向导来配置ObjectDataSource的另一个影响是Visual Studio设置了OldValuesParameterFormatString属性为original_{0}。这个属性值用来包含数据被编辑时的原始值,它在下面两种情况下非常有用:
·如果,当编辑一条记录时,用户可以修改主键的值。在这种情况下,新的主键的值和原始的主键值都需要提供,这样具有这个原始主键值的数据库记录才可以被找到然后才能将它的值更新。
·当使用开放式并发。开放式并发是为了保证同时操作的用户不至于覆盖另一个用户所做更改的一种技巧,这也是后面的教程中的一节(实现开放式并发 )。
这个OldValuesParameterFormatString属性指明了隐含对象的更新和删除方法中对应原始值的输入参数的名称。我们将在探讨开发式并发的时候更详细地讨论这个属性和它的目的。不过暂时我放下它,因为我们的BLL的方法并不需要这些原始的值因此我们删除这个属性,这一点很重要。如果让OldValuesParameterFormatString属性设置为除了默认值({0})以外的其它任何的值,都将在数据Web控件尝试调用ObjectDataSource的Update()或Delete()方法时引发一个错误,因为ObjectDataSource将尝试将这些原始值参数与UpdateParameters或DeleteParameters一起传入。
如果对此不是十分清楚,别担心,我们将在未来的章节中研究这个属性和它的效用。暂时,一定要完全地从声明语法中完全地删除这个属性或者将它设置为默认值({0})。
注意: 如果你只是简单地从设计视图的属性窗口删除这个OldValuesParameterFormatString属性的值,这个属性依旧会存在于声明语法中,不过被设置为一个空字符串。不幸地,这将依旧导致上面提到的同样的问题。所以,从声明语法里彻底地删除这个属性,或者从属性窗口将其设置为默认值,{0}。
第三步: 添加一个数据Web服务器控件并配置它为数据更改服务
一般ObjectDataSOurce被添加到页面并配置完成,我们可以添加一个数据Web服务器控件用来显示数据并提供一个最终用户修改数据的途径。我们将分别看看GridView、DetailsView和FormView,因为这些数据Web服务器控件在它们的数据更改功能和配置上都有所不同。
正如我们将在本文剩下的部分里看到的,通过GridView、DetailsView和FormView控件添加一个非常基本的编辑、插入和删除支持是真的非常简单,只需要勾选上一对CheckBox。现实中提供这样的功能有许多微妙之处和边缘案例,这要比仅仅点几下要棘手得多。但是,本教程里,只着眼于提供简单的数据修改功能。以后的章节将研究在现实中不容置疑地出现的问题。
从GridView中删除数据
首先,从工具箱拖拽一个GridView到设计器。然后,通过GridView的智能标记中从下拉列表中选择从而绑定ObjectDataSource到该GridView。在这里GridView的声明标记将是:
<asp:GridView runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"> <Columns> <asp:BoundField DataField="ProductID" HeaderText="ProductID" InsertVisible="False" ReadOnly="True" SortExpression="ProductID" /> <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" /> <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" /> <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" SortExpression="CategoryID" /> <asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit" SortExpression="QuantityPerUnit" /> <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" /> <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" SortExpression="UnitsInStock" /> <asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" /> <asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel" SortExpression="ReorderLevel" /> <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" SortExpression="Discontinued" /> <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" ReadOnly="True" SortExpression="CategoryName" /> <asp:BoundField DataField="SupplierName" HeaderText="SupplierName" ReadOnly="True" SortExpression="SupplierName" /> </Columns> </asp:GridView>
通过它的职能标记绑定GridView到ObjectDataSource有下面两点的好处: