EF Core «Вторая операция началась в этом контексте до завершения предыдущей операции» только при развертывании - PullRequest
1 голос
/ 24 января 2020

Я пытаюсь создать веб-API с очень простой c аутентификацией для тестирования.

Я создаю провайдер Context следующим образом:

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);

Класс контекста:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }

}

Я запускаю некоторых пользователей:

public static void Initialize(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.GetRequiredService<ApplicationDbContext>();
        var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        context.Database.EnsureCreated();
            ApplicationUser user = new ApplicationUser()
            {
                Email = "a@gmail.com",
                SecurityStamp = Guid.NewGuid().ToString(),
                UserName = "a@gmail.com"
            };
            ApplicationUser user2 = new ApplicationUser()
            {
                Email = "ali@gmail.com",
                SecurityStamp = Guid.NewGuid().ToString(),
                UserName = "ali@gmail.com"
            };
        userManager.CreateAsync(user, "Ali@123");
        userManager.CreateAsync(user2, "Ali@123");
    }

Затем я использую атрибут [Authorize] на моих контроллерах. Теперь, когда я вызываю этот API , он работает на 100% в Visual Studio при отладке, 0 проблем вообще. Однако при развертывании в IIS на той же машине я получаю сообщение об ошибке:

System.InvalidOperationException: 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.

         at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()

         at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()

Я перепробовал практически все, о чем я могу думать на данный момент, приведенное выше использование ApplicationDbContext - единственный раз, когда он напрямую взаимодействует, так почему же он выдает ошибку при развертывании, но работает совершенно нормально с теми же шагами при отладке.

1 Ответ

1 голос
/ 24 января 2020

Странная часть вашего вопроса в том, что он работает, когда вы отлаживаете. Это исключение означает, что ваш context используется двумя потоками одновременно, или двумя потоками в одном запросе, или двумя запросами.

Единственная причина, по которой я могу думать об этом, не происходит на вашем компьютере команда userManager.CreateAsync(user, "Ali@123"); завершает свое выполнение перед вызовом следующей строки. (БОЛЬШОЙ ГУДЕС)

Поскольку вы используете метод CreateAsync без await, следующая строка может быть выполнена до того, как первая закончит выполнение. И это поведение вызывает исключение с сообщением: «Вторая операция, запущенная в этом контексте до завершения предыдущей операции» *

Чтобы решить эту проблему, вам нужно await хотя бы первую CreateAsync звонок.

    await userManager.CreateAsync(user, "Ali@123");
    userManager.CreateAsync(user2, "Ali@123");
...