UPDATE Products SET ProductName = @ProductName, UnitPrice = @UnitPrice WHERE ProductID = @original_ProductID AND ProductName = @original_ProductName AND UnitPrice = @original_UnitPrice
就像我们将在本教程看到的一样,使SqlDataSource能实现开放式并发控制是很简单的事情。
第一步:创建一个支持开放式并发的SqlDataSource控件
打开SqlDataSource文件夹中的OptimisticConcurrency.aspx页面,从工具箱拖一个SqlDataSource控件到页面,设置其ID为ProductsDataSourceWithOptimisticConcurrency。在其智能标签里点“设置数据源”,数据库选为“NORTHWINDConnectionString”,点下一步。
图4:选“ORTHWINDConnectionString”数据库
在此例子里,我们将添加一个GridView控件以编辑表Products。所以在“Configure the Select Statement”界面选择从表Products返回ProductID, ProductName, UnitPrice和Discontinued列,如图5所示:
图5:从表Products返回ProductID, ProductName, UnitPrice和Discontinued列
然后,点“高级”按钮,打开“Advanced SQL Generation Options”对话框,选择“Generate INSERT, UPDATE, and DELETE statements”和“Use optimistic concurrency”2项,点“OK”(见图1)。再点下一步、完成,结束设置。
完成设置数据源向导后,花几分钟查看DeleteCommand和UpdateCommand属性,以及DeleteParameters和UpdateParameters标签。最快的方法是切换到“源模式”直接在页面代码查看,你会看到UpdateCommand的值像这样:
UPDATE [Products] SET [ProductName] = @ProductName, [UnitPrice] = @UnitPrice, [Discontinued] = @Discontinued WHERE [ProductID] = @original_ProductID AND [ProductName] = @original_ProductName AND [UnitPrice] = @original_UnitPrice AND [Discontinued] = @original_Discontinued
同时在<UpdateParameters>标签里有7个参数:
<asp:SqlDataSource runat="server" ...> <DeleteParameters> ... </DeleteParameters> <UpdateParameters> <asp:Parameter Type="String" /> <asp:Parameter Type="Decimal" /> <asp:Parameter Type="Boolean" /> <asp:Parameter Type="Int32" /> <asp:Parameter Type="String" /> <asp:Parameter Type="Decimal" /> <asp:Parameter Type="Boolean" /> </UpdateParameters> ... </asp:SqlDataSource>
同样的,DeleteCommand属性和<DeleteParameters>标签如下:
DELETE FROM [Products] WHERE [ProductID] = @original_ProductID AND [ProductName] = @original_ProductName AND [UnitPrice] = @original_UnitPrice AND [Discontinued] = @original_Discontinued
<asp:SqlDataSource runat="server" ...> <DeleteParameters> <asp:Parameter Type="Int32" /> <asp:Parameter Type="String" /> <asp:Parameter Type="Decimal" /> <asp:Parameter Type="Boolean" /> </DeleteParameters> <UpdateParameters> ... </UpdateParameters> ... </asp:SqlDataSource>
选择了“Use optimistic concurrency”选项后,不仅扩展了UpdateCommand 和DeleteCommand属性里的WHERE字句(同时在相关参数集里添加了参数),同时调整了以下2个属性:
1. 将ConflictDetection属性由“OverwriteChanges”(默认值)改为 “CompareAllValues ”
2. 将OldValuesParameterFormatString属性由“{0}”(默认值)改为 “original_{0}”
当数据Web控件调用SqlDataSource的Update()或Delete()方法时,它将传递原始值。当SqlDataSource的ConflictDetection属性设置为“CompareAllValues”时,就会将这些原始值添加到命令中。而OldValuesParameterFormatString属性则为这些原始值提供了命名规范,向导以“original_{0}”的形式为 UpdateCommand和DeleteCommand中的原始值以及<UpdateParameters>和<DeleteParameters>中的参数命名。
注意:由于我们没有使用SqlDataSource控件的插入功能,因此可以将InsertCommand 属性和<InsertParameters>标签清除。
正确地处理NULL值
不幸的是,当使用开放式并发的时候,由设置数据源向导自动生成的、扩展成包含WHERE字句的UPDATE和 DELETE命令不能处理那些含有NULL值的记录。为什么呢?先看SqlDataSource的UpdateCommand语句: