实体框架乐观并发与更新存储过程(Julie Lerman示例)

时间:2013-04-20 12:27:12

标签: stored-procedures entity-framework-5 updating optimistic-concurrency

使用更新存储过程了解并发问题时遇到了一些困难。我正在关注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");
            }
        }

Update SP看起来像:

UPDATE payments
SET paymentdate=@date,reservationID=@reservationID,amount=@amount, modifieddate=@modifiedDate
WHERE
paymentid=@paymentid AND ROWVERSION=@rowversion 
IF @@ROWCOUNT>0
SELECT RowVersion AS newTimeStamp FROM payments WHERE paymentid=@paymentid

并在映射中勾选“使用原始值”复选框,如下所示: https://dl.dropboxusercontent.com/u/135754/updatemapping.png

现在,当我尝试:

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

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

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

    然后,当我在SP映射中取消“使用原始值”作为时间戳值时,一切都以与上述相同的方式工作......我不明白它。我测试错了吗?应用程序何时应该输入'if'子句?

    提前致谢,欢呼!

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

1 个答案:

答案 0 :(得分:0)

我想我现在明白了。 当我尝试在调用savechanges之前手动更改rowversion(到一个随机byte []),然后:

  1. 取消选中使用原始值:'random byte []'被发送到DB并在更新存储过程中使用(在WHERE子句中),导致OptimisticConcurrencyException
  2. 使用原始值检查:rowversion最初从DB下载时所具有的值在更新存储过程中发送并使用(在WHERE子句中)
  3. 我想这就是使用原始值的原因......对我来说这似乎有点奇怪,谁会在同一个dbcontext中手动更改它?