Удерживает ли DbContext открытое соединение в течение своего жизненного цикла?

Вопрос довольно ясен. Поддерживает ли DbContext открытое соединение в течение своего жизненного цикла? Как насчет ядра EF?


person amiry jd    schedule 13.11.2018    source источник
comment
Нет и нет, если только вы не форсируете его, запустив транзакцию и оставив ее открытой. В противном случае он открывает соединение только при загрузке или сохранении и закрывает его после завершения. Вы можете легко убедиться в этом, используя профилировщик SQL Server или расширенные события.   -  person Panagiotis Kanavos    schedule 13.11.2018
comment
Хотя почему вопрос? Похоже, вы столкнулись с другой проблемой и считаете, что виновато управление соединениями? Или думаете, что соединения в пуле — это какая-то проблема? они не   -  person Panagiotis Kanavos    schedule 13.11.2018
comment
@PanagiotisKanavos Вот и ответ. Разместите его, чтобы его приняли. Спасибо.   -  person amiry jd    schedule 13.11.2018
comment
@PanagiotisKanavos, в прошлом я несколько раз видел проблемы со слишком большим количеством открытых соединений, потому что кто-то использовал неправильный шаблон для открытия/закрытия соединений. Так что, ИМХО, вопрос вполне актуален для таких, как я, которые только и ждут появления проблемы с каждым новым проектом ;) Кажется, что с EF Core нам больше не о чем беспокоиться?   -  person Andrzej Martyna    schedule 10.08.2020
comment
@AndrzejMartyna AndrzejMartyna нам не нужно было беспокоиться об этом и с ADO.NET - пул соединений существует с 2000 года, а DataSet/DataTable предназначен для работы в автономном режиме. Проблемы возникали только из-за плохой практики кодирования. К сожалению, люди также нашли способы сломать EF и EF Core, открывая и оставляя транзакции открытыми без какой-либо реальной причины, как правило, после использования общего антипаттерна репозитория.   -  person Panagiotis Kanavos    schedule 12.08.2020
comment
@PanagiotisKanavos, честно говоря, ты прав! но редко фреймворки поддерживают простые, элегантные способы расширенного использования, и тогда возникают проблемы и риски (например, недавно у меня была причина открыть одно соединение и передать его нескольким контекстам, чтобы разрешить транзакции - было довольно сложно найти хороший, шикарное решение)   -  person Andrzej Martyna    schedule 12.08.2020
comment
@AndrzejMartyna нет, нет - какая бы причина, по вашему мнению, у вас не была для этого единственного соединения и транзакций, у вас ее нет. Если вы думаете, что вам это нужно для Unit-of-Work, вы этого не сделаете - DbContext уже является Unit-of-Work, DbSet уже является репозиторием, а SaveChangesAsync будет хранить все ожидающие изменения. в одной транзакции. Вы можете создать отдельный DbContext для каждого сценария/прецедента/ограниченного контекста DDD, содержащий сущности, необходимые для этого сценария. Почему вам нужно использовать несколько DbContext?   -  person Panagiotis Kanavos    schedule 12.08.2020
comment
@AndrzejMartyna распространенная ошибка заключается в попытке реализовать, например, транзакцию на запрос в веб-приложениях с использованием методов Java. Однако эта транзакция является бизнес-транзакцией, а не транзакцией базы данных. Когда у вас уже есть UoW, вам не нужна явная транзакция для отката изменений — вы просто не сохраняете их! Если вы сохраняете частичные изменения, вы нарушили единицу работы.   -  person Panagiotis Kanavos    schedule 12.08.2020
comment
@PanagiotisKanavos, это прекрасно, когда вы начинаете проект с нуля, но у нас есть устаревшая система, в которой многие решения уже приняты (сознательно или нет) со смешанными подходами. Было невозможно внедрить UoW без перезаписи около сотни файлов, поэтому мы пошли по пути повторного использования существующих dbcontexts.   -  person Andrzej Martyna    schedule 12.08.2020


Ответы (1)


Как отмечают другие, нет, это не так, если вы вручную не откроете соединение и не передадите его конструктору DbContext.

Конкретный подробный ответ можно найти здесь https://stackoverflow.com/a/45330219/191148.

И комментарий @ajcvickers в https://github.com/aspnet/EntityFrameworkCore/issues/7810 очищает его:

Если EF создает объект DbConnection, то EF гарантирует его удаление при удалении DbContext. С другой стороны, если какой-то другой код создает объект DbConnection и передает его в EF, то другой код также несет ответственность за правильное удаление соединения.

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

person Mohsen Afshin    schedule 13.11.2018
comment
Большое спасибо. Я также нашел эту ссылку: brentozar.com /archive/2015/07/ с комментариями Джули Лерман. Она описывает, что именно происходит с базовой связью. - person amiry jd; 13.11.2018