asp.net

位置:IT落伍者 >> asp.net >> 浏览文章

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


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

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

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操作不需要OldValuesConflictDetection只对Update和Delete操作有意义

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

<script runat=server

Protected Sub SqlDataSource_Updated(sender As Object e As SqlDataSourceStatusEventArgs)

If eAffectedRows = Then

ResponseWrite(Row changed update aborted<br />)

End If

End Sub

Protected Sub SqlDataSource_Deleted(sender As Object e As SqlDataSourceStatusEventArgs)

If eAffectedRows = Then

ResponseWrite(Row changed delete aborted<br />)

End If

End Sub

</script>

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

<asp:GridView ……>

<Columns>

<asp:CommandField ShowDeleteButton=True ShowEditButton=True />

<asp:TemplateField HeaderText=ContactID InsertVisible=False SortExpression=ContactID

<ItemTemplate>

<asp:Label ID=Label runat=server Text=<%# Bind(ContactID) %>></asp:Label>

</ItemTemplate>

<EditItemTemplate>

<asp:Label ID=Label runat=server Text=<%# Eval(ContactID) %>></asp:Label>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText=ContactName SortExpression=ContactName

<ItemTemplate>

<asp:Label ID=Label runat=server Text=<%# Bind(ContactName) %>></asp:Label>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox ID=TextBox runat=server Text=<%# Bind(ContactName) %>></asp:TextBox>

</EditItemTemplate>

</asp:TemplateField>

</Columns>

</asp:GridView>

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

Protected Sub DetailsView_ItemUpdated(ByVal sender As Object ByVal e As SystemWebUIWebControlsDetailsViewUpdatedEventArgs)

If eAffectedRows = Then

使DetailsView处于编辑模式并与数据库同步

eKeepInEditMode = True

DetailsViewDataBind()

用用户输入的值重新填充DetailsView

Dim t As TextBox

t = DetailsViewRows()Cells()Controls()

tText = eNewValues(OrderDate)

t = DetailsViewRows()Cells()Controls()

tText = eNewValues(ShipCountry)

ErrorPanelVisible = True

Else

ErrorPanelVisible = False

End If

End Sub

Protected Sub DetailsView_ModeChanging(ByVal sender As Object ByVal e As SystemWebUIWebControlsDetailsViewModeEventArgs)

If eCancelingEdit = True AndAlso ErrorPanelVisible = True Then

ErrorPanelVisible = False

End If

End Sub

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

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

               

上一篇:如何由ASP.NET 1.1移植到ASP.NET 2.0

下一篇:asp.net防止页面刷新或后退引起重复提交