none
ASP.Net Core подключение к БД RRS feed

  • Вопрос

  • Здравствуйте!

    Подскажите как правильно настроить подключение к БД, чтоб избегать ошибок: "The connection was not closed. The connection's current state is connecting.".

    Строка подключения к БД: "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=ИмяБД;Trusted_Connection=False;User ID=ИмяПользователя;Password=пароль;MultipleActiveResultSets=true;" }

    //ConfigureServices
    services.AddDbContextPool<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    //DbContext
    public class ApplicationDbContext : IdentityDbContext
    {
      public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
      {
        Database.MigrateAsync();
      }
    }
    //Controller
    private readonly UserManager<IdentityUser> _userManager;
    public HomeController(UserManager<IdentityUser> userManager)
    {
      _userManager = userManager;
    }
    private  IdentityUser GetIdentityUser()
    {
      IdentityUser IUser = null;
      using (var UM = _userManager)
      {
       IUser = UM.Users.FirstOrDefault(u => u.UserName == User.Identity.Name);
      }
      return IUser;
    }

    1 октября 2019 г. 14:12

Ответы

  • >Это похоже на проблему с синхронизацией потоков?

    Ну, это первое, что приходит в голову. Пытаемся закрыть соединение, которое еще не открылось - типичное состояние гонки.

    >Нет, просто пока не знаю как в конструкторе написать await, если конечно конструктор это поддерживает.

    Конструктор, конечно, не может быть асинхронным методом, но в нем можно сделать .Wait(), чтобы дождаться окончания синхронно. 

    • Помечено в качестве ответа Liliya Muray 2 октября 2019 г. 13:37
    2 октября 2019 г. 10:45

Все ответы

  • "The connection was not closed. The connection's current state is connecting" как бы намекает, что проблема не с настройкой подключения, а скорее с синхронизацией потоков. У вас из разных потоков что-нибудь делается с этим DbContext? То, что Database.MigrateAsync() - видимо, асинхронный метод - вызывается без ожидания окончания его выполнения, это так и задумано?

    2 октября 2019 г. 7:52
  • >>"The connection was not closed. The connection's current state is connecting" как бы намекает, что проблема не с настройкой подключения, а скорее с синхронизацией потоков. У вас из разных потоков что-нибудь делается с этим DbContext?

    Это практически весь код по работе с БД. В базе только таблицы Identity и работа с ними через стандартные формы. Ошибка возникает даже при работе на локальной машине, когда один пользователь и один запрос к БД, например при частом обновлении страницы. Это похоже на проблему с синхронизацией потоков?

    >>То, что Database.MigrateAsync() - видимо, асинхронный метод - вызывается без ожидания окончания его выполнения, это так и задумано?

    Нет, просто пока не знаю как в конструкторе написать await, если конечно конструктор это поддерживает.

    2 октября 2019 г. 10:04
  • >Это похоже на проблему с синхронизацией потоков?

    Ну, это первое, что приходит в голову. Пытаемся закрыть соединение, которое еще не открылось - типичное состояние гонки.

    >Нет, просто пока не знаю как в конструкторе написать await, если конечно конструктор это поддерживает.

    Конструктор, конечно, не может быть асинхронным методом, но в нем можно сделать .Wait(), чтобы дождаться окончания синхронно. 

    • Помечено в качестве ответа Liliya Muray 2 октября 2019 г. 13:37
    2 октября 2019 г. 10:45
  • Вы правы, проблема была в конструкторе ApplicationDbContext. Соединение передавалось до завершения его создания. После добавления .Wait() проблема вроде не наблюдается. Убрала проверку миграций из конструктора, проблема тоже не повторяется, нужно будет правильно написать код по проверке миграций... Чтоб она выполнялась один раз на запуск приложения, а не как у меня было, при каждом подключении.

    P.S. Теперь миграция выполняется скорее всего правильно с await и один раз на запуск приложения:

            public static async Task Main(string[] args)
            {
                IWebHost webHost = CreateWebHostBuilder(args).Build();
                using (var scope = webHost.Services.CreateScope())
                {
                    var myDbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                    await myDbContext.Database.MigrateAsync();
                }
                await webHost.RunAsync();
            }

    • Изменено Liliya Muray 2 октября 2019 г. 14:57
    2 октября 2019 г. 13:47