网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > ASP.NET技巧
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.从数据库导出数据到word、excel、.
.ASP 2.0 数据绑定函数Eval()的机.
.ASP.NET 2.0 中的母版页详解.
.Asp.Net细节性问题精萃.
.Asp.net中防止用户多次登录的方法.
.ASP.NET Atlas对JavaScript的扩展.
.net中统一的存储过程调用方法.
.编写高性能Web应用程序的10个入门.
.ASP.NET中数据校验部分的封装与应.
.101个微软提供的Visual Studio 2.
.ASP.Net 2.0 图形控件简述.
.一个通用的分页类.
.ASP.NET中文件上传下载方法集合.
.ConnectString中enlist设置的含义.
.Asp.Net中使用水晶报表.
.用 md5 加密数据库中的用户密码.
.如何改变asp.net项目名称.
.使用FileUpload控件上传图片并自.
.ASP.NET2.0登陆控件的使用(常见.
.安全的设置DropDownList等列表类.

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

发表日期:2006-11-28


  前面我们提到,数据绑定控件把传递给数据源的值存放在相互独立的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>

  你可以温和地处理冲突检测错误,可以通过提示用户下层数据被改变了,向用户显示改变过的值, 让用户选择提交或放弃自己的操作。下面的例子演示处理冲突检测的一种可行方法。请注意,DetailsView的RowUpdated事件参数传递了可用于检测用户输入的值的字典。你还可以设置这个事件参数的KeepInEditMode属性,使用户在决定如何处理冲突期间,DetailsView处于编辑模式。这个例子所试验方法与上面一个例子类似,同时打开两个窗口来创建冲突更新。

Protected Sub DetailsView1_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs)
 If e.AffectedRows = 0 Then
  ' 使DetailsView处于编辑模式并与数据库同步
  e.KeepInEditMode = True
  DetailsView1.DataBind()
 
  ' 用用户输入的值重新填充DetailsView
  Dim t As TextBox
  t = DetailsView1.Rows(1).Cells(1).Controls(0)
  t.Text = e.NewValues("OrderDate")
  t = DetailsView1.Rows(2).Cells(1).Controls(0)
  t.Text = e.NewValues("ShipCountry")

  ErrorPanel.Visible = True
 Else
  ErrorPanel.Visible = False
 End If
End Sub

Protected Sub DetailsView1_ModeChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewModeEventArgs)
 If e.CancelingEdit = True AndAlso ErrorPanel.Visible = True Then
  ErrorPanel.Visible = False
 End If
End Sub

  使用ObjectDataSource的时候,情况也类似。请注意,由于数据源的ConflictDetection属性被设置为CompareAllValues,数据源将查找一个可接受Contact对象的每个字段的原始值的UpdateContact重载。

  你还可以同时使用DataObjectTypeName属性和CompareAllValues。在这种情况下,ObjectDataSource查找仅接受两个参数(都是Contact)的UpdateContact重载。第一个参数是存放新值的Contact对象,第二个参数是存放旧值的Contact对象。

上一篇:一个读取扩展名为xml的资源文件的方法 人气:3914
下一篇:比较:HyperLink控件、LinkButton控件 之间的异同 人气:5129
浏览全部ASP.NET 2.0的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐