Как управлять SQL-соединениями с помощью служебного класса? - PullRequest
4 голосов
/ 21 октября 2009

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

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

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

Как лучше всего справиться с этим?

ОБНОВЛЕНИЕ: Все еще думаю об этом, но до сих пор кажется, что лучше всего по-прежнему возвращать хранилище данных, использовать CommandBehavior.CloseConnection, а затем доверять тому, кто когда-либо использует класс для вызова dr.Close ()

Ответы [ 5 ]

3 голосов
/ 21 октября 2009

Рассматривали ли вы Microsoft Enterprise Library ?

public List<User> GetUsers()
{
    List<User> result = new List<User>();

    Database db = new
    Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(this.connectionString);
    DbCommand cmd = db.GetStoredProcCommand("GetUsers");

    using (IDataReader rdr = db.ExecuteReader(cmd))
    {
        while (rdr.Read())
        {
            User user = new User();
            FillUser(rdr, user);                   
            result.Add(user);
        }
    }
    return result;

}
2 голосов
/ 21 октября 2009

Мы используем что-то подобное, и оно работает очень хорошо при большой громкости.

    public SqlDataReader ExecuteReader(string command, SqlParameter[] parameters)
    {
        SqlDataReader reader = null;

        using (SqlConnection conn = new SqlConnection())
        using (SqlCommand cmd = conn.CreateCommand())
        {
            conn.Open();

            cmd.CommandText = command;
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.AddRange(parameters);

            reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        return reader;
    }

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

1 голос
/ 21 октября 2009

У меня та же структура - служебные классы с методами, которые извлекают данные и возвращают заполненные DataTables (или заполняют / обновляют переданный им DataTable) - по тем же причинам: хранение соединений с базой данных отдельно от остальных код и убедитесь, что они открыты только при необходимости и закрыты как можно скорее. Тем более, что данные хранятся в различных внутренних системах, и я хочу представить только один интерфейс для моего приложения и не беспокоиться о деталях.

В вашей ситуации есть одно отличие: мы (вообще) не создаем объекты из строк в DataTables, а работаем непосредственно с данными в строках. Я считаю, что работать с DataTables просто и эффективно.

Кроме этого, я лично не вижу ничего плохого в этом подходе и считаю, что он очень хорошо работает для наших целей.

0 голосов
/ 26 июля 2010

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

однако это решение не будет работать для использования внутри веб-методов (веб-сервисов). Я полагаю, вам придется адаптировать технику для использования веб-службы. Ваша последняя строка в веб-методе должна быть вызовом события. Поэтому, когда вы пишете свой класс веб-сервиса, определите событие с именем WebMethodCompleted. Вы, вероятно, получите ссылку на экземпляр веб-службы с помощью техники, упомянутой в статье. Получив ссылку, вы можете зарегистрировать событие в своем служебном классе. Просто не забудьте вызвать событие в веб-методе.

Счастливого программирования.

0 голосов
/ 26 октября 2009

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

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

IMO, начиная с ADO.Net 2.0, таблицы данных могут хорошо работать даже в крупномасштабных удаленных ситуациях. Они предоставляют специальный двоичный формат удаленного взаимодействия и просты в работе. Добавьте немного сжатия, и вы даже не используете большую полосу пропускания для больших наборов данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...