Entity Framework Core - безопасность потоков и блокировка контекста с помощью блокировки {}. Мой выбор в порядке? - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть конечная точка службы API, созданная с помощью gRP C. У меня есть один класс для реализации операций с базой данных:

public SSImpl(BaseContext cnx)
        {
            this.cnx = cnx;

        }

Базовый контекст -

  public class BaseContext : DbContext
    {
        public BaseContext()

        {
            Database.EnsureDeleted();
            Database.EnsureCreated();

        }

        public DbSet<User> _Users { get; set; }

    }

Я сделал это так, потому что я хочу легко переключаться между версией приложения dev / prod. Итак, в большей части моих приложений я использовал IDisposable и magi c using(var con = new Context()), но теперь мне нужно добавить контекст с его новым типом, основанным на классе реализации BaseContext to Database. Поэтому я использовал конструктор, как описано выше, и я могу использовать любой контекст, основанный на BaseContext.

InMemoryContext cnx = new InMemoryContext();
SQLiteContext sqlitecnx = new SQLiteContext();
SSImpl impl = new SSImpl(sqlitecnx);
SSImpl impl2 = new SSImpl(cnx);

Теперь у меня проблема с использованием контекста. В тестировании у меня есть исключение

A second operation started on this context before a previous asynchronous operation completed.

и

"A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.")'

Итак, мой вопрос и идеи:

Разве это лучше использовать, например, для блокировки операций синхронизации * 1020? *

 lock (cnx)
            {

                cnx._Users.Add(new User
                {
                    Nick = nick,
                    Password = password,
                    Details = new UserDetails
                    {
                        Email = email
                    }

                });

                cnx.SaveChanges();
            }

Чтобы быть уверенным, что операция 1 завершена до начала операции 2, или, может быть, Мне следует использовать await SaveChangesAsync вместо SaveChanges ? Я не уверен, потому что теперь я не могу использовать контекст IDisposable, и я не знаю, будет ли SaveChangesAsync делать что-то вроде очереди операций с БД? Если это так, что с Selects? Не будет ли это противоречивым? Или, может быть, мне нужно использовать отдельные контексты для создания и обновления и чтения?

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