0

我在使用更新存储过程了解并发问题时遇到了一些困难。我下面的朱莉·勒曼的编程实体框架和她给出了一个例子,下面的代码:使用更新存储过程的实体框架乐观并发性(Julie Lerman示例)

using (var context = new BAEntities()) 
     { 
      var payment = context.Payments.First(); 
      if (payment.PaymentDate != null) 
      { 
       payment.PaymentDate = payment.PaymentDate.Value.AddDays(1); 
      } 
      var origRowVersion = payment.RowVersion; 
      try 
      { //BREAKPOINT #1 
       context.SaveChanges(); 
       var newRowVersion = payment.RowVersion; 
       if (newRowVersion == origRowVersion) 
       { 
        Console.WriteLine("RowVersion not updated"); 
       } 
       else 
       { 
        Console.WriteLine("RowVersion updated"); 
       } 
      } 
      catch (OptimisticConcurrencyException) 
      { 
       Console.WriteLine("Concurrency Exception was thrown"); 
      } 
     } 

更新SP的样子:

UPDATE payments 
SET [email protected],[email protected],[email protected], [email protected] 
WHERE 
[email protected] AND [email protected] 
IF @@ROWCOUNT>0 
SELECT RowVersion AS newTimeStamp FROM payments WHERE [email protected] 

和“使用原始值”复选框中打勾映射,它看起来像这样: https://dl.dropboxusercontent.com/u/135754/updatemapping.png

现在,当我尝试:

  1. 按照原样运行代码,然后在调试器中检查的newRowVersion与origRowversion相同,但应用程序输入'else'子句(为什么它首先是相同的,我刚刚更改了它?是它调试器的问题?)

  2. 运行代码,但在BREAKPOINT#1我更新Management Studio中的付款对象,SaveChanges引发OptimisticConcurrencyException。我认为这是预期的结果。

每次查看SQL事件探查器时,都会将原始版本的时间戳发送到服务器。

然后,当我在时间戳值的SP映射中取消“使用原始值”时,所有操作都与上面描述的方式相同......我不明白这一点。我测试它错了吗?应用何时应该输入'if'条款?

在此先感谢,欢呼!

编辑: 我添加了newTimeStamp作为Update SP映射的返回值。现在我可以看到RowVersion的更新值是从DB正确取出的。但我仍然看不到有“使用原始值”选中和取消选中之间的区别...

回答

0

我想我现在明白了。 当我尝试调用的SaveChanges然后之前手动更改rowversion(以随机的byte []):

  1. 使用原始值不选择:“随机字节[]”被发送到数据库,并在更新中使用存储过程(在WHERE子句中),导致OptimisticConcurrencyException
  2. 使用原始值检查:该值rowversion有当它最初被从数据库下载的发送和使用更新存储过程(WHERE子句中)

我想这就是Use Original Value的用途......对我来说,这似乎有点奇怪,你是谁ld在相同的dbcontext中手动更改它?