Нужно ли принудительно 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".