科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件ASP.NET 2.0高级数据处理之冲突检测

ASP.NET 2.0高级数据处理之冲突检测

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在默认情况下,SqlDataSource和ObjectDataSource会忽略OldValues字段,只使用Keys和Values

作者:陶刚编译 来源:天极开发 2007年11月6日

关键字: ASP.NET 数据处理 检测 Windows

  • 评论
  • 分享微博
  • 分享邮件
前面我们提到,数据绑定控件把传递给数据源的值存放在相互独立的Keys、Values(新值)和 OldValues字典中。在默认情况下,SqlDataSource和ObjectDataSource会忽略OldValues字段,只使用Keys和Values。这种行为是由数据源的ConflictDetection属性检测的,在默认情况下这个属性的值被设置为OverwriteChanges。OverwriteChanges模式意味着"为了更新或删除记录,仅仅匹配主键值"。这种操作意味着,记录的更新或删除是不考虑该记录的下层值是否改变过了。在通常情况下,理想的状态是,只有当数据行的值与最初选择的值完全匹配的时候,才让Update或Delete操作成功。在这种理想情况下,如果另外一个用户在你选择某一行和更新该行的之间也更新了这一行,你的更新操作就会失败。通过把ConflictDetection属性设置为CompareAllValues,数据源也支持这种操作。在这种模式下,数据源会把OldValues应用到命令或方法上,它会使用这些值来确保在更新或删除记录之前,更新或删除操作必须与记录的所有值都匹配。你还必须把OldValuesParameterFormatString属性设置为一个有效的.NET框架组件格式化字符串(例如"original_{0}"),来指明OldValues和Keys字典中的参数如何重新命名以便与NewValues参数区分开来。

  下面的代码示例显示了SqlDataSource控件在OverwriteChanges和CompareAllValues模式下使用的典型的SQL命令。ID字段被假定为主键字段。请注意,后面一个命令在WHERE子句中比较数据行的所有原始值,而不是仅仅比较主键。在这种情况下,数据源的OldValuesParameterFormatString需要被设置为"original_{0}"。

SELECT [ID], [Name], [Address] from [Contacts]
-- OverwriteChanges
UPDATE [Contacts] SET [Name] = @Name, [Address] = @Address WHERE [ID] = @ID
DELETE FROM [Contacts] WHERE [ID] = @ID

-- CompareAllValues
UPDATE [Contacts] SET [Name] = @Name, [Address] = @Address WHERE [ID] = @original_ID
AND [Name] = @original_Name AND [Address] = @original_Address
DELETE FROM [Contacts] WHERE [ID] = @original_ID AND [Name] = @original_Name
AND [Address] = @original_Address

  请注意,Insert操作不需要OldValues,ConflictDetection只对Update和Delete操作有意义。

  下面的例子演示了冲突发生时的行为。为了运行这个例子,你必须在两个独立的浏览器窗口中打开例子的两个实例(两次点击"Run Sample")。接着在两个窗体的同一行上都点击"Edit"按钮,使该行进入编辑模式。在第一个窗口中改变一个值并点击"Update",请注意这个更新是成功的。在第二个窗口中,在该行中输入一个新值并点击"Update",这个更新操作没有成功,因为下层数据行的值已经被第一个更新操作改变过了。这个示例检测了Updated或Deleted事件参数的AffectedRows属性,它为0确认了冲突发生了。

<script runat="server">
Protected Sub SqlDataSource1_Updated(sender As Object, e As SqlDataSourceStatusEventArgs)
 If e.AffectedRows = 0 Then
  Response.Write("Row changed, update aborted<br />")
 End If
End Sub

Protected Sub SqlDataSource1_Deleted(sender As Object, e As SqlDataSourceStatusEventArgs)
 If e.AffectedRows = 0 Then
  Response.Write("Row changed, delete aborted<br />")
 End If
End Sub
</script>

  当Update或Delete使用模板化UI的时候,使用了Bind语法的双向(two-way)数据绑定字段的旧值都会被保留。对于Delete来说,这意味着在ItemTemplate中你必须给数据绑定的值使用Bind语法,其目的是为了保留删除操作所需要的旧值。下面的例子演示了这种技术。

<asp:GridView ……>
 <Columns>
  <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
  <asp:TemplateField HeaderText="ContactID" InsertVisible="False" SortExpression="ContactID">
   <ItemTemplate>
    <asp:Label ID="Label1" runat="server" Text='<%# Bind("ContactID") %>'></asp:Label>
   </ItemTemplate>
   <EditItemTemplate>
    <asp:Label ID="Label3" runat="server" Text='<%# Eval("ContactID") %>'></asp:Label>
   </EditItemTemplate>
  </asp:TemplateField>
  <asp:TemplateField HeaderText="ContactName" SortExpression="ContactName">
   <ItemTemplate>
    <asp:Label ID="Label2" runat="server" Text='<%# Bind("ContactName") %>'></asp:Label>
   </ItemTemplate>
   <EditItemTemplate>
    <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("ContactName") %>'></asp:TextBox>
   </EditItemTemplate>
  </asp:TemplateField>
 </Columns>
</asp:GridView>
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章