Обрабатывать параллелизм в Entity Framework - PullRequest
4 голосов
/ 02 марта 2012

Я ищу лучший способ обработки параллелизма при использовании Entity Framework.Самое простое и наиболее рекомендуемое (также в стеке) решение описано здесь: 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);

        }
    }

Я не уверен, если я пойму, как 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 Ответ

4 голосов
/ 02 марта 2012

Да, даже второе сохранение может вызвать исключение OptimisticConcurrencyException, если - как вы говорите - что-то меняется между Refresh() и SaveChanges().

Данный пример представляет собой очень простую логику повторных попыток: если вам нужно повторить попытку более одного раза или разрешить конфликт более сложным способом, вам лучше создать цикл, который будет повторяться n раз, чем вложения try / catch больше, чем этот единственный уровень.

...