Нужно ли принудительно Dispose после запроса LINQ?

Мой администратор базы данных говорит, что существует слишком много подключений, и он считает, что это мой код в .net, который оставляет их открытыми.

Я сначала использую запросы LINQ и EF.

Пример метода:

 public List<Stuff> GetStuff()
 {
      var db = new DBContext();

      var results =  db.stuff.toList();

      return results;
 }

Нужно ли мне утилизировать db var, как только я закончу? Я понимаю, что мне не нужно было в EF и LINQ. Пожалуйста, укажите мне документацию Microsoft об управлении соединением в коде или лучших практиках для соединений LINQ/EF и db.

Update:

Я добавил

db.Connection.Close();
db.Dispose();

и я все еще вижу открытое соединение в SQL после выполнения двух строк. Есть ли причина, по которой она не закрывается, когда я заставляю ее закрываться?

Ответы

Ответ 1

По умолчанию DbContext автоматически управляет соединением для вас. Поэтому вам не нужно явно вызывать Dispose.

Сообщение в блоге по теме: Ссылка

Но я считаю, что не утилизация может вызвать проблемы с производительностью, если вы обрабатываете множество запросов. Вы должны добавить инструкцию using, чтобы узнать, вызывает ли это проблему в вашем случае.

Ответ 2

Вы должны слушать своего администратора базы данных! Да, используйте using. Не оставляйте соединения без необходимости. Вы должны подключиться, вести свою работу с db и закрыть это соединение, освободив его для другого процесса. Это особенно актуально в системах с большими объемами.

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

В ситуациях с большими объемами это просто просит о катастрофе. Сервер Sql выделяет так много соединений для каждого приложения (может быть указано в строке подключения). Что происходит, процессы будут тратить время на ожидание соединений, чтобы освободить их, если они не будут быстро закрыты. Обычно это приводит к тайм-аутам или взаимоблокировкам в некоторых ситуациях.

Конечно, вы можете настроить соединение с сервером Sql и т.д., но каждый раз, когда вы настраиваете настройку, вы делаете компромисс. Вы должны учитывать, что выполняются резервные копии, выполняются другие задания и т.д. Вот почему мудрый разработчик будет слушать их предупреждения DBA. Это не всегда все о коде...

Ответ 3

Я просто спросил этот тот же вопрос на Programmers.SE. Роберт Харви дал отличный ответ.

В общем, вам не нужно использовать использование операторов с контекстами данных Entity Framework. Ленивые коллекции - одна из причин.

Я рекомендую вам прочитать весь ответ на Programmers.SE, а также ссылки, которые Роберт предоставляет в ответ.

Ответ 4

Структура сущности использует, насколько я знаю, объединение пулов по умолчанию, чтобы уменьшить накладные расходы при создании новых подключений каждый раз. Закрыты ли соединения при закрытии приложения?

Если это так, вы можете попытаться уменьшить максимальный размер пула в строке подключения или полностью отключить объединение пулов. См. здесь для ссылки на возможные варианты в вашей строке соединения.

Ответ 5

Да, если ваш метод определяет Единицу работы; нет, если что-то более примитивное. (P.S. что-то где-то в вашем коде должно определить Единицу работы, и эта вещь должна быть обернута в using (var context = new DbContext()) {} или эквивалент.)

И если вы принадлежите к мысли о том, что ваш DbContext является вашей единицей работы, тогда вы всегда будете обертывать этого плохого мальчика блоком using: локальное кэширование данных, ранее извлеченных во время контекста время жизни вместе с методом SaveChanges действуют как своего рода легкая транзакция, а ваш Dispose (без вызова SaveChanges) является вашим откатом (тогда как ваш SaveChanges является вашим Commit).

Ответ 6

Проверьте это, здесь стандартный протокол о том, как использовать объекты IDisposable. https://msdn.microsoft.com/en-us/library/yh598w02.aspx

В нем говорится:

"Как правило, когда вы используете объект IDisposable, вы должны объявить его и создать его в операторе using."

Поскольку у них есть доступ к неуправляемым ресурсам, вы всегда должны учитывать инструкцию "using".