C #: Как я могу сократить свой код для запуска хранимой процедуры? - PullRequest
0 голосов
/ 15 ноября 2011

Я большой поклонник того, чтобы мой код был простым и аккуратным, чтобы его можно было многократно использовать, с чем я борюсь, это с помощью устройства чтения данных для различных типов объектов, я нашел его в методе и нашел были проблемы с закрытыми или оставленными открытыми соединениями. Так что я вынужден, в то же время, скопировать и вставить код, что я ненавижу !!! Есть ли способ, которым я могу уменьшить это, чтобы я мог поместить его в метод и сделать его многоразовым и красивым?

ENT_AuctionBid ret = new ENT_AuctionBid();      

try
        {
            SqlParameter[] Params = new SqlParameter[]{ 
                    new SqlParameter("@ID", ID ) 
            };

            using (SqlConnection conn = new SqlConnection(this.ConnectionString))
            {
                using (SqlCommand command = new SqlCommand("GetItem", conn))
                {
                    SqlDataReader reader;
                    command.CommandType = CommandType.StoredProcedure;

                    conn.Open();

                    command.Parameters.AddRange(Params);
                    reader = command.ExecuteReader(CommandBehavior.SingleRow);

                    while (reader.HasRows)
                    {
                        while (reader.Read())
                        {
            // 
                            ret = this.Convert(reader);
                        }

                        reader.NextResult();
                    }

                    reader.Close();
                }
            }
        }
        catch (Exception ex)
        {

        }  
return ret;

Ответы [ 7 ]

1 голос
/ 15 ноября 2011

Вы можете сделать это, используя намного меньше строк:

// Skipped creating temp variable
try {
   using (SqlConnection conn = new SqlConnection(this.ConnectionString))
   using (SqlCommand command = new SqlCommand("GetItem", conn) { CommandType = CommandType.StoredProcedure} ) {

      command.Parameters.AddWithValue(@ID, ID);
      conn.Open();

      // reader is IDisposable, you can use using
      using (var reader = command.ExecuteReader(CommandBehavior.SingleRow)) {
          // Skipped parsing multiple result sets, you return after the first
          // otherwise there's no point using SingleRow 
          // If nothing is read, return default value
          return reader.Read() ? this.Convert(reader) : new ENT_AuctionBid();
      }
   }
}
catch (Exception ex) {
    // Handle your exception here
}  
// Return default value for error
return new ENT_AuctionBid();

Все соединения закрываются с помощью этого кода (потому что используется use).Нет ненужных циклов, потому что вы ожидаете только одну строку.И временная переменная не нужна, поэтому объект abondend не создается, только когда он используется, он создается.

1 голос
/ 15 ноября 2011

Вы должны использовать SQLDataAdapter.
Вот хороший пример того, как его использовать: http://www.dotnetperls.com/sqldataadapter

Кроме того, вы можете рассмотреть возможность перехода на Entity Framework, это сделает ваш доступ к данным намного, намного проще, но может быть сложным в существующем проекте.

0 голосов
/ 15 ноября 2011

Вы можете использовать служебный файл, например SqlHelper.cs из блока приложений Microsoft Data Access.Тогда весь код, который вам нужен, это:

using (SqlDataReader sdr = SqlHelper.ExecuteReader(this.ConnectionString, "GetItem", ID))
  {
    while (sdr.Read())
    {
      ret = this .Convert(sdr);
    }
  }
0 голосов
/ 15 ноября 2011

В своих проектах я обычно решаю эту проблему, создавая служебный класс, который содержит все методы для доступа к БД и управления всем, что связано с подключением к БД и адаптером. Например, класс DBSql, который содержит соединение (соединение SqlConnection;) в качестве закрытого члена и следующие методы:

//execute the query passed to the function
public System.Data.DataSet ExecuteQuery(string query)
//returns if a query returns rows or not
public bool HasRows(string query)
//execute commands like update/insert/etc...
public int ExcuteNonQuery(string sql)

В моем классе вы просто передаете строку, и класс инициализирует различные DataAdapter и Command для его выполнения и возвращает набор данных. Очевидно, вы можете усложнить управление параметрами / транзакцией и всем остальным. Таким образом, вы уверены, что соединение и объект всегда обрабатываются одинаково, и, надеюсь, правильно.

0 голосов
/ 15 ноября 2011

Создание вспомогательных методов для создания и возврата объекта типа SqlCommand.Передайте объект подключения этому вспомогательному методу, а также имя хранимой процедуры и список параметров (если есть).Если у вас есть разные объекты, созданные из устройства чтения данных, передайте устройство чтения данных конструктору и дайте ему сгенерировать объект на основе этих данных.Что касается закрытия соединения, вы всегда должны попытаться ... поймать ... наконец.В разделе, наконец, закройте соединение.

0 голосов
/ 15 ноября 2011

Это немного меньше: -

    try
        {

            using (SqlConnection conn = new SqlConnection(this.ConnectionString))
            {
                using (SqlCommand command = new SqlCommand("GetItem", conn))
                {
                    command.Paramaters.AddWithValue("@ID",ID);
                    command.CommandType = CommandType.StoredProcedure;

                    conn.Open();

                    reader = command.ExecuteReader();

                    while (reader.Read())
                    {

            // 
                            ret = this.Convert(reader);

                    }

                }
            }
        }
        catch (Exception ex)
        {

        }  
0 голосов
/ 15 ноября 2011

Вы можете начать использовать LINQ-to-SQL, который имеет собственную систему DataClass, в которой вы просто перетаскиваете таблицы базы данных и хранимые процедуры.Тогда вам просто нужно создать экземпляр в верхней части ваших классов - private MyCustomDataClass _db = new MyCustomDataClass();, а затем вы можете просто набрать _db.<Here all datatables and SPROCs will appaer for you to choose>.

Пример (с момента, когда все SPROC добавлены в DataClass)

private MyCustomDataClass _db = new MyCustomDataClass();

public void MethodToRunSPROC(string email, Guid userId)
{
    _db.MySPORC_AddEmailToUser(email, userId);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...