2012-06-27 3 views
7

Я работаю с объектом DAL, который написан в макете, похожей на следующий код. Я просто упростил код кода, чтобы показать установку.Должны ли вы повторно использовать объекты SqlConnection, SqlDataAdapter и SqlCommand?

public class UserDatabase : IDisposable 
{ 
    private SqlDataAdapter UserDbAdapter; 
    private SqlCommand UserSelectCommand; 
    private SqlCommand UserInsertCommand; 
    private SqlCommand UserUpdateCommand; 
    private SqlCommand UserDeleteCommand; 

    private System.Data.SqlClient.SqlConnection SQLConnection; 

    public UserDatabase() 
    { 
     this.SQLConnection = new System.Data.SqlClient.SqlConnection(ConnectionString); 
     this.UserDbAdapter= new SqlDataAdapter(); 
     this.UserDbAdapter.DeleteCommand = this.UserDeleteCommand; 
     this.UserDbAdapter.InsertCommand = this.UserInsertCommand; 
     this.UserDbAdapter.SelectCommand = this.UserSelectCommand; 
     this.UserDbAdapter.UpdateCommand = this.UserUpdateCommand; 
    } 

    private bool FillUsers(DataSet UserDataSet, out int numberOfRecords) 
    { 
     bool success = true; 

     numberOfRecords = 0; 
     string errorMsg = null; 

     this.UserDbAdapter.SelectCommand = this.GetUsersSelectCommand(); 

     numberOfRecords = UserDbAdapter.Fill(UserDataSet, UsersTableName); 

     return success; 
    } 

    private SqlCommand GetUserSelectCommand() 
    { 
     if (this.UserSelectCommand==null) 
      this.UserSelectCommand= new System.Data.SqlClient.SqlCommand(); 
     this.UserSelectCommand.CommandText = "dbo.Users_Select"; 
     this.UserSelectCommand.CommandType = System.Data.CommandType.StoredProcedure; 
     this.UserSelectCommand.Connection = this.SQLConnection; 
     this.UserSelectCommand.Parameters.Clear(); 
     this.UserSelectCommand.Parameters.AddRange(new System.Data.SqlClient.SqlParameter[] { 
     new System.Data.SqlClient.SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Variant, 0, System.Data.ParameterDirection.ReturnValue, false, ((byte)(0)), ((byte)(0)), "", System.Data.DataRowVersion.Current, null)}); 

     return UserSelectCommand; 
    } 

Есть несколько других функций типа заполняющего, которые написаны таким же образом, повторное использование объекта Connection, SqlCommands и SqlDataAdapter. SqlDataAdapter управляет открытием и закрытием SqlConnection внутренне.

Так что мой вопрос многогранный. Этот дизайн плохой? Если да, то почему?

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

public bool FillUsers(DataSet UserDataSet) 
    { 
     using (SqlConnection conn = new SqlConnection(ConnectionString)) 
     { 
      using (SqlCommand command = GetUsersSelectCommand()) 
      { 
       using (SqlDataAdapter adapter = new SqlDataAdapter(command, conn)) 
       { 
        adapter.Fill(UserDataSet, UsersTableName); 
       } 
      } 
     } 
    } 

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

+0

Вы измеряли проблему с производительностью, которая, по вашему мнению, нуждается в оптимизации? Соединения базы данных объединены по дизайну. Не нужно «переливать» верх. – spender

+0

Аналогичный вопрос, который я задал несколько лет назад: http://stackoverflow.com/questions/226127/multiple-single-instance-of-linq-to-sql-datacontext – spender

+0

Проблемы с производительностью не связаны. Я начинаю новый проект и нуждаюсь в объекте доступа к данным, и мне было любопытно, было ли это «правильно» или был лучший способ. – Equixor

ответ

8

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

С учетом SqlConnection, когда вы удаляете соединение, базовое соединение просто будет возвращено в пул. Это не обязательно «закрыто», как вы думаете. Лучше всего позволить пулу подключений выполнять эту работу. Here - это ссылка на соединение MSDN с ADO.NET. Пытаясь заставить его делать то, для чего оно не предназначено (некоторые называют это оптимизацией, что удивительно), как правило, это путешествие по кроличьей дыре.

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

+0

Верхний код не удаляет любой объект, пока объект UserDatabase не будет удален. Похоже, повторное использование их противоречит этой дизайнерской практике? – Equixor

+0

@Equixor: Я имел в виду более конкретно SqlConnection. Имя вашего класса UserDatabase немного вводит в заблуждение, поскольку оно не является реальной базой данных. Возможно, вы можете создать метод с именем GetUsers(), который вернет список пользователей. Ваш второй пост кода правильный. Хранение их вокруг хуже (и иногда приводит к трудному воспроизведению ошибок) –

+0

Хорошо спасибо. Я уверен, что общий дизайн этого также может быть улучшен. Большинство классов DAL, которые у нас есть, похожи на это и заполняют наборы данных, которые затем используются BLL. – Equixor

Смежные вопросы