我正在寻找在使用实体框架时处理并发的最佳方式。最简单和最值得推荐的(也堆栈)解决方案说明如下: http://msdn.microsoft.com/en-us/library/bb399228.aspx 它看起来像:在实体框架中处理并发性
try
{
// Try to save changes, which may cause a conflict.
int num = context.SaveChanges();
Console.WriteLine("No conflicts. " +
num.ToString() + " updates saved.");
}
catch (OptimisticConcurrencyException)
{
// Resolve the concurrency conflict by refreshing the
// object context before re-saving changes.
context.Refresh(RefreshMode.ClientWins, orders);
// Save changes.
context.SaveChanges();
Console.WriteLine("OptimisticConcurrencyException "
+ "handled and changes saved");
}
但是否足够?如果Refresh()和第二个SaveChanges()之间的内容发生变化,该怎么办?将会有未捕获的OptimisticConcurrencyException?
编辑2:
我认为这将是最终的解决方案:
int savesCounter = 100;
Boolean saveSuccess = false;
while (!saveSuccess && savesCounter > 0)
{
savesCounter--;
try
{
// Try to save changes, which may cause a conflict.
int num = context.SaveChanges();
saveSuccess = true;
Console.WriteLine("Save success. " + num.ToString() + " updates saved.");
}
catch (OptimisticConcurrencyException)
{
// Resolve the concurrency conflict by refreshing the
// object context before re-saving changes.
Console.WriteLine("OptimisticConcurrencyException, refreshing context.");
context.Refresh(RefreshMode.ClientWins, orders);
}
}
我不知道,如果Iunderstand如何刷新()的作品。它是否刷新整个上下文?如果是,为什么需要额外的参数(实体对象)?还是只刷新指定的对象? 例如,在这种情况下,我应该为刷新()第二个参数进行传递:
Order dbOrder = dbContext.Orders.Where(x => x.ID == orderID);
dbOrder.Name = "new name";
//here whole the code written above to save changes
应该dbOrder?
+1这是我第一次阅读时对这个例子的反对意见!一般来说,在异常处理程序中执行“风险”操作(saveChanges)是不好的做法。我很惊讶在官方文档中看到这一点。 – 2012-03-02 14:05:10
Re:你的改变,看起来不错。如果说100次重试无法补救这种情况,我会小心谨慎,这可能会打破循环。总是很难调试以永无止境的循环结束的问题。即使他们不应该发生;-) – 2012-03-02 14:42:32
尝试在这个链接的方法它使用不同的方式来处理concurreny,这可能是更可靠的评价遵循: - http://www.asp.net/mvc/tutorials /工具入门与 - EF-使用-MVC /处理并发与 - 的实体框架式-AN-ASP净MVC应用程序 – 2012-03-16 03:38:19