Я ищу лучший способ обработки параллелизма при использовании Entity Framework. Самый простой и наиболее рекомендуемый (также в стеке) решение описано здесь: http://msdn.microsoft.com/en-us/library/bb399228.aspx И это выглядит следующим образом:Обработка параллелизма в Entity Framework
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?
EDIT 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 как работает Refresh(). Обновляет ли он весь контекст? Если да, то почему он принимает дополнительные аргументы (объекты объектов)? Или он обновляет только указанные объекты? Например, в этой ситуации то, что должно быть передано в Refresh() второй аргумент:
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) в обработчике исключений. Я был поражен, увидев это в официальной документации. –
Re: Ваше изменение, оно выглядит хорошо. Я, быть осторожным, вероятно, поставил бы способ разбить цикл, если бы 100 попыток не смогли исправить ситуацию. Всегда трудно отлаживать проблемы, которые заканчиваются бесконечными циклами. Даже если они никогда не должны произойти ;-) –
Попробуйте подход в этой ссылке, он использует другой способ обработки concurreny, который может быть более надежным, чтобы следить за: - http://www.asp.net/mvc/tutorials/получение стартером-с-эф-используя-MVC/обработка-параллелизм-с-сущность-рамки-в-ан-Asp-нетто-MVC-приложений –