EF вторая транзакция получить Базовый поставщик не удалось открыть - PullRequest
0 голосов
/ 07 сентября 2018

Это до EF 6. В моей компании есть процесс, который работает со всеми остальными нашими клиентами. Процесс открывает соединение с базой данных клиентов, одновременно считывает 1000 записей и фиксирует это в нашей базе данных.

Для этого клиента мы прекрасно читаем и фиксируем первые 1000 записей. Когда он начинает читать снова, я получаю сообщение «Основной провайдер не удалось открыть». Я понимаю, что транзакции EF открываются и закрываются для каждого чтения, поэтому, когда он пытается повторно открыть соединение для следующего чтения, происходит сбой.

Подробности: мы подключаемся через VPN к клиентской базе данных.

Поток кода:

  connection.open()

  create datareader

  while datareader.read()
  get 1000 records
  bulk commit
  db.SaveChanges
  get next 1000 records
  and so on until it gets all records

После первого SaveChanges, когда мы получаем ошибку. Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Спасибо всем за помощь. Оказывается, что потерянное соединение было с нашей базой данных, а не с клиентом. Не совсем уверен, почему, но, похоже, помогло использование метода BulkInsert для создания объекта SqlBulkCopy внутри блока using. Мы также в тот момент, когда это не удалось, восстановили связь. Это немного глупо, но работает.

0 голосов
/ 07 сентября 2018

До EF6 DbContext закрывал соединение, когда оно было утилизировано, независимо от того, принадлежало оно ему или нет. Начиная с EF6, контекст учитывает флаг contextOwnsConnection, передаваемый конструктору (см. здесь ). Из вашего псевдокода неясно, как вы создаете экземпляр соединения и контекст, поэтому предположите, что вы создаете контекст в цикле и пропускаете открытое соединение. Если это так, у вас есть несколько вариантов:

  • Обновление до EF6 или
  • Использовать только один DbContext для всех сохранений или
  • Загрузить все записи в память и обработать их порциями, каждый в своем собственном DbContext, или
  • Загрузите их кусками и обработайте их кусками

Если вы избегаете использовать один и тот же контекст для обработки по соображениям производительности, вы можете использовать .AsNoTracking (). Есть статья на MSDN о настройке производительности EF на случай, если вам понадобится больше.

...