Должен ли я открывать и закрывать db для каждого запроса?

Я использую старую школу ADO.net с C# так что есть много такого рода кода. Лучше ли сделать одну функцию на запрос и открывать и закрывать БД каждый раз или запускать несколько запросов с одним и тем же подключением? Ниже приведен только один запрос, например purpose only.

 using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnectMain"].ConnectionString))
    {
        // Add user to database, so they can't vote multiple times
        string sql = " insert into PollRespondents (PollId, MemberId) values (@PollId, @MemberId)";

        SqlCommand sqlCmd = new SqlCommand(sql, connection);

        sqlCmd.Parameters.Add("@PollId", SqlDbType.Int);
        sqlCmd.Parameters["@PollId"].Value = PollId;

        sqlCmd.Parameters.Add("@MemberId", SqlDbType.Int);
        sqlCmd.Parameters["@MemberId"].Value = Session["MemberId"];

        try
        {
            connection.Open();
            Int32 rowsAffected = (int)sqlCmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            //Console.WriteLine(ex.Message);
        }
    }

5 ответов


в большинстве случаев Открытие и закрытие соединения на запрос-это путь (как указал Крис Лайвли). Однако есть некоторые случаи, когда вы столкнетесь с узкими местами производительности с этим решением.

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

всегда обязательно используйте обертку "using", чтобы избежать утечек mem, независимо от того, какой шаблон вы используете.


Ну, вы могли бы измерить; но пока вы не using соединения (поэтому они удаляются, даже если вы получаете исключение), и пул включен (для SQL server он включен по умолчанию), это не будет иметь большого значения; закрытие (или удаление) просто возвращает базовый подключение в пул. Оба подхода работают. Извините, это не очень помогает ;p

просто не держите открытое соединение, пока вы делаете другую длительную работу без БД. Закройте его и снова откройте; вы можете на самом деле получите то же самое базовое соединение, но кто-то другой (другой поток) мог бы использовать его, пока вас не было.


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

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

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

в качестве примера у нас есть несколько страниц, которые будут выполнять обновление до 50 запросов, чтобы составить страницу. Поскольку существует разветвленный код для определения запросов для запуска, каждый из них обернут своим собственным using (connection...) положения.

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


Ну, как всегда, это зависит. Если у вас есть 5 вызовов базы данных для выполнения одного и того же вызова метода, вероятно, следует использовать одно соединение.

однако удержание соединения, пока ничего не происходит, обычно не рекомендуется с точки зрения масштабируемости.


ADO.NET старая школа теперь? Ты заставила меня почувствовать себя старой. Для меня Rogue Wave ODBC с использованием Borland C++ в Windows 3.1-это старая школа.

ответ, в общем, вы хотите понять, как водителей данных. Понять такие понятия, как пул соединений и научиться профилировать транзакционные издержки, связанные с подключением / отключением и выполнением запросов. Затем возьмите это знание и примените его в своей ситуации.