使用更新存储过程了解并发问题时遇到了一些困难。我正在关注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
现在,当我尝试:
按原样运行代码,然后在调试器中检查的newRowVersion与origRowversion相同,但应用程序输入'else'子句(为什么它首先是相同的,我刚刚更改了它?它是调试器问题吗?)
运行代码,但在BREAKPOINT#1中我更新了Management Studio中的付款对象,SaveChanges会抛出OptimisticConcurrencyException。我认为这是预期的结果。
每次查看SQL事件探查器时,都会将原始版本的时间戳发送到服务器。
然后,当我在SP映射中取消“使用原始值”作为时间戳值时,一切都以与上述相同的方式工作......我不明白它。我测试错了吗?应用程序何时应该输入'if'子句?
提前致谢,欢呼!
编辑: 我添加了newTimeStamp作为Update SP映射的返回值。现在我可以看到RowVersion的更新值是从DB中正确获取的。但我仍然看不到选中“使用原始值”和未选中之间的区别......
答案 0 :(得分:0)
我想我现在明白了。 当我尝试在调用savechanges之前手动更改rowversion(到一个随机byte []),然后:
我想这就是使用原始值的原因......对我来说这似乎有点奇怪,谁会在同一个dbcontext中手动更改它?