在实体框架中,我想使用存储过程使用乐观并发对表执行更新。如果不修改现有的更新存储过程,我就无法使其工作。我正在尝试确定是否有办法映射我现有的存储过程,以便在没有更新任何行时发生并发异常。
一些背景信息:
- 我已经在我的 .edmx 文件中映射了更新存储过程(包括时间戳(列
-
我现有的存储过程如下所示(实际的表名和列显然被省略了(:
UPDATE Table SET Column = @Column1, Column2 = @Column2 .... WHERE PK = @PK AND Timestamp = @Timestamp SELECT PK, Column1, Column2, ....., Timestamp FROM Table WHERE PK = @PK
-
如果更新失败(由于时间戳不匹配(,存储过程的选择部分仍将返回一行。
当我将存储过程修改为以下内容时:
UPDATE Table SET Column = @Column1, Column2 = @Column2 ....
WHERE PK = @PK AND Timestamp = @Timestamp
IF @@ROWCOUNT > 0
SELECT PK, Column1, Column2, ....., Timestamp
FROM Table WHERE PK = @PK
然后一切按预期工作,并发生并发错误。
或者,如果我使存储过程返回输出参数,并将该输出参数映射到实体框架的 .edmx 文件中的"受影响的行参数",则并发错误也会按预期工作。
我发现,这个解决方案(即使用输出参数(在这里得到了最好的解释:http://petermannerhult.wordpress.com/2010/10/01/entity-framework-4-with-optimistic-concurrency-and-stored-procedures/
不过,上述步骤似乎都不是必需的,因为我假设实体框架只能使用更新的行数来确定它是否应该引发并发异常。我在 ADO.NET DataSet 中使用了这些完全相同的存储过程(具有乐观并发性(,没有任何问题。所以我的问题是,如何在不进行修改的情况下使用现有的存储过程在实体框架中启用乐观并发?
在 EDMX 设计器的"存储过程映射"窗口中,每个属性旁边有两个复选框。 Use Original Value
和Rows Affected Parameter
. 如您所指出的,Rows Affected Parameter
要求您在 proc 中使用输出参数。 但是,如果选择Use Original Value
作为时间戳,则会比较它们,并在两者不匹配时引发OptimisticConcurrencyException
。 这应该允许您获取异常,而无需修改过程。
如果确实不想更改存储过程代码,可以将从存储过程返回的时间戳与传入存储过程的时间戳进行比较。如果不同,则存在并发错误。