Соединения с SQL Server автоматически объединяются в приложении ASP.NET: один пул для каждой отдельной строки соединения. Если вы следуете рекомендациям и скрываете код своей базы данных в DAL, строка подключения которого постоянна во всем приложении, то вы всегда будете работать с одиночным пулом объектов подключения.
Так что это значит для вашего подхода к базе данных? Ну, во-первых, это означает, что «закрытие соединения» действительно означает «возвращение соединения в пул», а не действительно закрытие ссылки приложения на SQL Server. Таким образом, закрытие и повторное открытие - это не , что большой сделки. Тем не менее, с учетом сказанного, есть несколько лучших практик, которым нужно следовать здесь.
Во-первых, вы не хотите исчерпывать соединения в вашем пуле, даже если ваше приложение значительно расширяется. То есть никогда не думайте по очереди «пользователь на этой странице» - думайте в терминах «тысячи людей, использующих эту страницу».
Во-вторых, несмотря на то, что закрытие и повторное открытие соединения не так обременительно, вам, как правило, нужно открывать соединение как поздно , насколько это возможно, использовать его до завершения, а затем закрывать рано , насколько это возможно. Единственное исключение - если у вас трудоемкий процесс, который должен наступить после извлечения некоторых данных и до сохранения или извлечения других данных.
В-третьих, я настоятельно рекомендую не открывать соединение в начале жизненного цикла страницы и не закрывать его в конце жизненного цикла другим способом. Зачем? Потому что худшее , что вы можете сделать, это оставить соединение открытым, потому что вы забыли добавить логику, чтобы закрыть его. Да, они в конечном итоге будут закрыты, когда GC начнет действовать, но, опять же, если вы подумаете о "тысячах людей, использующих эту страницу *, шанс для реальной проблемы станет очевидным.
Теперь, что если вы скажете, что вы уверены, что закроете соединение, потому что вы всегда делаете это в каком-то ключевом, логическом месте (например, метод Page_Unload). Что ж, это здорово , если вы можете с уверенностью сказать, что никогда не выбросите ошибку, которая выпрыгнет из жизненного цикла страницы. Что вы не можете. Так что ... не открывайте в одном методе жизненного цикла страницы и не закрывайте в другом.
Наконец, я настоятельно рекомендую реализовать DAL, который управляет соединениями с базой данных и предоставляет инструменты для работы с данными. Кроме того, создайте слой бизнес-логики (BLL), который использует эти инструменты для предоставления типизированных объектов в ваш пользовательский интерфейс (например, объекты «модель»). Если вы реализуете объекты BLL с интерфейсом IDisposable, вы всегда можете обеспечить безопасность соединения, используя область действия. Это также позволит вам держать соединение с базой данных открытым в течение очень короткого периода времени: просто откройте объект BLL, перетащите данные в локальный объект или список, а затем закройте объект BLL (выйдите из области видимости ). Затем вы можете работать с данными, возвращаемыми BLL после соединения было закрыто.
Итак ... как это выглядит. Итак, на ваших страницах (пользовательском интерфейсе) вы будете использовать классы бизнес-логики, например:
using (BusinessLogicSubClass bLogic = new BusinessLogicSubClass())
{
// Retrieve and display data or pull from your UI and update
// using methods built into the bLogic object
.
.
.
} // <-- Going out of scope will automatically call the dispose method and close the database connection.
Ваш BusinessLogicSubClass будет производным от объекта BusinessLogic, который реализует IDisposable. Он создаст экземпляр вашего класса DAL и откроет соединение следующим образом:
public class BusinessLogic : IDisposable
{
protected DBManagementClass qry;
public BusinessLogic()
{
qry = new DBManagementClass();
}
public void Dispose()
{
qry.Dispose(); <-- qry does the connection management as described below.
}
... other methods that work with the qry class to
... retrieve, manipulate, update, etc. the data
... Example: returning a List<ModelClass> to the UI ...
}
когда класс BusinessLogic выходит из области видимости, автоматически вызывается метод Dispose, поскольку он реализует интерфейс IDisposable.
Ваш класс DAL будет иметь подходящие методы:
public class DBManagementClass : IDisposable
{
public static string ConnectionString { get; set; } // ConnectionString is initialized when the App starts up.
public DBManagementClass()
{
conn = new SqlConnection(ConnectionString);
conn.Open();
}
public void Dispose()
{
conn.Close();
}
... other methods
}
Учитывая то, что я описал до сих пор, DAL не имеет для IDisposable. Тем не менее, я активно использую свой класс DAL в своем тестовом коде, когда тестирую новые методы BLL, поэтому я создал DAL как IDisposable, чтобы я мог использовать конструкцию «using» во время тестирования.
Следуйте этому подходу, и, по сути, вам больше никогда не придется думать о пуле соединений.