ASP.NET2.0快速入门--高级数据方案(3)

  上篇系列文章http://mqingqing123.cnblogs.com/archive/2006/03/23/356592.html

(本节继续介绍一些更容易忽略的问题,供大家参考,由于内容太多,所以分3节看来是不行了,只要用(3)而不是(下))

    ObjectDataSource 不依赖特定的参数顺序,而只是查找具有匹配的参数名称的方法。注意,为了解析方法重载,ObjectDataSource 没有使用参数的 Type 或 Size。只对参数的名称进行匹配,因此如果业务对象上有两个具有相同名称和参数名称但具有不同参数类型的方法,ObjectDataSource 将无法区分它们。可以在事件中更改 ObjectDataSource 参数的名称和值,类似于上面的 SqlDataSource 示例。但是,如果使用 DataObjectTypeName 指定要传递给 Update、Insert 和 Delete 操作的特定数据对象类型,您将不能修改参数名称 -- 只能修改值。如果需要修改参数名称,则不要使用 DataObjectTypeName,而只需在代码中的数据源事件中手动构造相应的数据对象。

     到目前为止,我们使用的所有数据源参数都是 Input 参数,用于将值传入数据源操作。参数也可以是双向的,例如 InputOutput、Output 和 ReturnValue 参数。可以使用 Parameter 对象的属性 Direction 指定参数的方向性。若要在数据源操作完成之后检索这些参数的值,应处理相应的操作后事件,例如 Selected、Updated、Inserted 或 Deleted 事件,以便从传递给这些事件的事件参数中获得参数值。SqlDataSourceStatusEventArgs 有一个 Command 属性,可以使用该属性获得返回值和输出参数,如下面的示例所示。注意,对于双向参数,在 SqlDataSource 中将 Parameter 对象的 Size 属性设置为适当的值很重要。

  

C# Return Values and Output Parameters

     为此目的,ObjectDataSourceStatusEventArgs 类型支持 OutputParameters 集合和 ReturnValue 属性,如下一个示例所示。注意,在此示例中,Update 操作的返回值用于确定受该操作影响的行数。若要将此值传回数据绑定控件(例如通过 GridViewUpdatedEventArgs AffectedRows 属性),可以将 ObjectDataSourceStatusEventArgs 的 AffectedRows 属性设置为此返回值。

  

C# Return Values and Output Parameters (Object)

     输出参数的另一种常见用途是检索插入数据库中的行的主键值,主键值是标识列,其中的键值不是作为插入操作的参数指定的,而是在插入操作发生时由数据库服务器自动生成的。下一个示例演示了此项技术。

  

C# Retrieving Identity After Insert

  

使用冲突检测

如在前面的主题中所提到的,数据绑定控件在单独的 Keys、Values(新值)和 OldValues 字典中将值传递给数据源。默认情况下,SqlDataSource 和 ObjectDataSource 忽略 OldValues 字典,仅应用 Keys 和 Values。这种行为由数据源的 ConflictDetection 属性确定,该属性默认设置为 OverwriteChanges。OverwriteChanges 模式本质上意味着“仅为了更新或删除记录而匹配主键值”。这种行为意味着不管记录的基础值是否已更改,都要更新或删除该记录。通常,仅当行的值准确匹配最初选择的值时才允许 Update 或 Delete 成功是更为适宜的。这样,如果另一个用户在从您选择行到更新该行这段时间内更新了该行,您的更新操作将会失败。数据源通过将 ConflictDetection 属性设置为 CompareAllValues 来支持这种方法。在这种模式下,数据源向命令或方法应用 OldValues 参数,该命令或方法可以在更新或删除记录之前使用这些值确保更新或删除操作匹配该记录的所有这些值。还必须将 OldValuesParameterFormatString 属性设置为有效的 .NET Framework 格式字符串(例如“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

 

下面的示例演示在数据绑定控件级别和数据源级别对 Keys、Values 和 OldValues 字典进行的参数枚举(当 ConflictDetection 设置为 CompareAllValues 时)。出于演示目的,实际的 Update、Delete 和 Insert 操作被取消了。还要注意 Insert 操作不需要 OldValues。ConflictDetection 仅对 Update 和 Delete 有意义。

  

C# Conflict Detection Parameters

 

下一个示例演示冲突发生时的行为。若要运行此示例,请在单独的浏览器窗口中打开该示例的两个实例(单击“Run Sample”(运行示例)两次)。然后对两个窗口中的相同行单击“Edit”(编辑)按钮,以便将该行置于编辑模式。在第一个窗口中,更改某个行值并单击“Update”(更新),并注意更新是成功的。在第二个窗口中,可以为相同行输入新值并单击 “Update”(更新),但是更新不会成功,这是因为基础行值被第一个更新操作更改了。该示例检测到 Updated 或 Deleted 事件参数的 AffectedRows 属性为 0,从而确认发生了冲突。

 

 C# Conflict Detection (Update and Delete)

 

 在将模板化 UI 用于 Update 或 Delete 时,使用 Bind 语句进行了双向数据绑定的字段的旧值被保留下来。对于 Delete,这意味着必须使用 Bind 语句对 ItemTemplate 中的值进行数据绑定才能保留删除操作的旧值。下面的示例演示了此项技术。

  

C# Conflict Detection Using Templates

 

 

您可以在基础行已更改时为用户提供提交或中止操作的选择,并向用户显示已更改的值以便他们能够将这些值与自己的更新进行比较,这样可以恰当地处理冲突检测错误。下面的示例演示一种用于处理冲突检测错误的可能方法。注意,DetailsView RowUpdated 事件参数传递可用于检查用户输入的值的字典。还可以设置此事件参数的 KeepInEditMode 属性,以便在用户确定冲突处理方式时将 DetailsView 保持在编辑模式下。像前一示例一样,您可以打开两个窗口以创建冲突的更新,以试验此示例。

 

 

C# Handling Conflicting Updates

 

 下一个示例使用 ObjectDataSource 演示与上面相同的方案。注意,由于数据源 ConflictDetection 属性被设置为 CompareAllValues,数据源将查找接受 Contact 对象的每个字段的原始值的 UpdateContact 重载。

 

 

C# Conflict Detection w/ ObjectDataSource

 

 

还可以将 DataObjectTypeName 属性与 CompareAllValues 结合使用。在本例中,ObjectDataSource 查找正好接受两个类型均为 Contact 的参数的 UpdateContact 重载。第一个参数将是使用用于更新的新值填充的 Contact 对象,第二个参数将是使用原始值填充的 Contact 对象。

 

 

C# Conflict Detection w/ ObjectDataSource (DataObjectTypeName)

 

posted @ 2006-03-27 09:14  启明星工作室  阅读(2384)  评论(2编辑  收藏  举报