在ASP.NET 2.0中操作数据之四十八:对SqlDataSource控件使用开放
完成设置数据源向导后,花几分钟查看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 ID="ProductsDataSourceWithOptimisticConcurrency" runat="server" ...> <DeleteParameters> ... </DeleteParameters> <UpdateParameters> <asp:Parameter Name="ProductName" Type="String" /> <asp:Parameter Name="UnitPrice" Type="Decimal" /> <asp:Parameter Name="Discontinued" Type="Boolean" /> <asp:Parameter Name="original_ProductID" Type="Int32" /> <asp:Parameter Name="original_ProductName" Type="String" /> <asp:Parameter Name="original_UnitPrice" Type="Decimal" /> <asp:Parameter Name="original_Discontinued" 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 ID="ProductsDataSourceWithOptimisticConcurrency" runat="server" ...> <DeleteParameters> <asp:Parameter Name="original_ProductID" Type="Int32" /> <asp:Parameter Name="original_ProductName" Type="String" /> <asp:Parameter Name="original_UnitPrice" Type="Decimal" /> <asp:Parameter Name="original_Discontinued" Type="Boolean" /> </DeleteParameters> <UpdateParameters> ... </UpdateParameters> ... </asp:SqlDataSource> 选择了“Use optimistic concurrency”选项后,不仅扩展了UpdateCommand 和DeleteCommand属性里的WHERE字句(同时在相关参数集里添加了参数),同时调整了以下2个属性: 1. 将ConflictDetection属性由“OverwriteChanges”(默认值)改为 “CompareAllValues ” 当数据Web控件调用SqlDataSource的Update()或Delete()方法时,它将传递原始值。当SqlDataSource的ConflictDetection属性设置为“CompareAllValues”时,就会将这些原始值添加到命令中。而OldValuesParameterFormatString属性则为这些原始值提供了命名规范,向导以“original_{0}”的形式为 UpdateCommand和DeleteCommand中的原始值以及<UpdateParameters>和<DeleteParameters>中的参数命名。 注意:由于我们没有使用SqlDataSource控件的插入功能,因此可以将InsertCommand 属性和<InsertParameters>标签清除。 正确地处理NULL值 不幸的是,当使用开放式并发的时候,由设置数据源向导自动生成的、扩展成包含WHERE字句的UPDATE和 DELETE命令不能处理那些含有NULL值的记录。为什么呢?先看SqlDataSource的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 表Products的UnitPrice列的值允许为NULL,如何某条记录的UnitPrice确实为NULL,那么WHERE字句的“[UnitPrice] = @original_UnitPrice”总是为False,NULL = NULL总是返回False。所以凡是y包含NULL值的记录不能被编辑或删除,因为UPDATE和DELETE命令中的WHERE字句不能返回记录。 注意:这个漏洞最早于2004年6月报告给微软,据业内传言,微软将在ASP.NET的下一个版本修补该漏洞。 为修补该漏洞,我们需要在UpdateCommand和DeleteCommand属性里手工修改所有允许为NULL值的列。一般来说,将[ColumnName] = @original_ColumnName to改成: ( ([ColumnName] IS NULL AND @original_ColumnName IS NULL) OR ([ColumnName] = @original_ColumnName) ) 你可以在属性窗口的UpdateQuery或DeleteQuery选项的代码声明里修改,或者在设置数据源向导的“指定自定义SQL语句或存储过程”选项的“更新”和“删除”标签里修改。确保在UpdateCommand和DeleteCommand的WHERE字句里做相同的修改。如下: UPDATE [Products] SET [ProductName] = @ProductName, [UnitPrice] = @UnitPrice, [Discontinued] = @Discontinued WHERE [ProductID] = @original_ProductID AND [ProductName] = @original_ProductName AND (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL) OR ([UnitPrice] = @original_UnitPrice)) AND [Discontinued] = @original_Discontinued DELETE FROM [Products] WHERE [ProductID] = @original_ProductID AND [ProductName] = @original_ProductName AND (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL) OR ([UnitPrice] = @original_UnitPrice)) AND [Discontinued] = @original_Discontinued 第2步:为GridView控件添加编辑和删除项 (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |