Транзакционный SaveChangesAsync в EF - PullRequest
1 голос
/ 11 марта 2019

Я хочу сохранить изменения в списке объектов Person в базе данных транзакционно.Я реализовал эту функцию, но не знаю, нужно ли мне обернуть await Task.WhenAll(tasks); в TransactionScope или этого кода уже достаточно, чтобы его получить.

    public class MyService {

        public MyContext Context { get; }

        public MyService(
            IDatabaseInitializer<MyContext> initializer
        ) {
            Context = new MyContext(initializer);
        }

        public async Task<int> AddOrUpdateDataAsync(IEnumerable<Person> persons)
        {
            List<Task> tasks = new List<Task>();
            try
            {
                foreach (Person person in persons)
                {
                    person.Status = Status.Finish;
                    person.Changed = DateTime.Now;
                    person.Role = Role.Worker;
                    MyContext.Persons.AddOrUpdate(person);
                    tasks.Add(await MyContext.SaveChangesAsync(););
                }

                await Task.WhenAll(tasks);
                return 1;
            }
            catch (EntityCommandExecutionException ex)
            {
                return 0;
            }
        }

    }

Ответы [ 2 ]

2 голосов
/ 11 марта 2019

Если вы точно не уверены в том, что делаете, я не предлагаю вам обрабатывать исключение, возвращая 0. Я всегда предпочитаю обрабатывать исключение на самом внешнем стеке и регистрировать исключение, а затем предпринимать надлежащие действия. И если это возможно, я предлагаю вам использовать промежуточное программное обеспечение для обработки ошибок (это зависит от используемой вами структуры, подхода и ситуации).

С другой стороны, вам не нужно обновлять каждый объект один за другим. Вы можете позвонить SaveChangesAsync после всех выполненных операций.

try
{
    foreach (Person person in persons)
    {
        person.Status = Status.Finish;
        person.Changed = DateTime.Now;
        person.Role = Role.Worker;
        MyContext.Persons.AddOrUpdate(person);
    }

    var affectedRows = await MyContext.SaveChangesAsync();
    return (int)(persons.Count == affectedRows);
}
catch (EntityCommandExecutionException ex)
{
    return 0;
}
1 голос
/ 11 марта 2019
tasks.Add(await MyContext.SaveChangesAsync(););

должно быть без ожидания

tasks.Add(MyContext.SaveChangesAsync());

И ваш код начинает работать. (выражение await возвращает асинхронный результат, без await возвращает задачу, которая будет выполнена позже) Но, как упоминалось ранее, не следует выполнять SaveChangesAsync () каждый раз, когда объект добавляется в контекст, это может быть сделано для всех добавленных объектов за один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...