2013-05-17 2 views
3

Эй, ребята, вы можете дать мне несколько советов. Я заметил, что правильный способ открытия и закрытия соединений с базой данных - использовать using statement, которые автоматически используют интерфейс IDisposable для освобождения ресурсов (пожалуйста, поправьте меня, если я ошибаюсь).Насколько я могу использовать заявления? Есть предел?

Итак, я решил начать использовать его, но код начал выглядеть немного проводным после более чем 3. Не могли бы вы рассказать мне, если я использовал его неправильно? Это событие кнопки, где я использую оператор using для создания некоторых объектов классов MySql.

private void buttonAdicionar_Click(object sender, EventArgs e) 
{ 
    using (MySqlConnection con = new MySqlConnection(Properties.Settings.Default.ConnectionString)) 
    { 
     using (MySqlDataAdapter da = new MySqlDataAdapter()) 
     { 
      using (DataTable dt = new DataTable()) 
      { 
       try 
       { 
        using (MySqlCommand cmd = new MySqlCommand("SELECT codigo, descricao, unidMedida, vlUnitario FROM tab_estoque WHERE codBar = @codBar;", con)) 
        { 
         cmd.Parameters.Add("@codBar", MySqlDbType.VarChar).Value = this.textBoxCodBarras.Text; 

         con.Open(); 
         da.SelectCommand = cmd; 
         da.SelectCommand.ExecuteNonQuery(); 
         da.Fill(dt); 

         // Caso haja alguma linha no DataSet ds então existe um produto com o codigo de barra procurado no banco de dados 
         if (dt.Rows.Count == 1) 
         { 
          bool itemIgual = false; 
          int rowIndex = 0; 

          // Passa por todas as linhas do carrinho de compras para verificar se existe outro item igual 
          foreach (DataGridViewRow dgvCarrinhoRow in dataGridViewCarrinho.Rows) 
          { 
           // Verifica se o produto da linha do carrinho de compra é o mesmo do código de barras 
           if (dgvCarrinhoRow.Cells[1].FormattedValue.ToString() == dt.Rows[0][0].ToString()) 
           { 
            // Verifica se estão tentando vender uma certa quantidade de um produto que esteja acima da quantidade do mesmo no estoque 
            if (this.VerificarSeExcede(Convert.ToInt32(dgvCarrinhoRow.Cells[1].FormattedValue), Convert.ToInt32(dgvCarrinhoRow.Cells[3].FormattedValue) + 1) == 1) 
            { 
             // Adiciona mais um na quantidade do item no carrinho de compra 
             dgvCarrinhoRow.Cells[3].Value = Convert.ToInt32(dgvCarrinhoRow.Cells[3].FormattedValue) + 1; 
             // Multiplica o VL. ITEM. pela nova quantidade e armazena o resultado em VL. ITEM 
             dgvCarrinhoRow.Cells[6].Value = String.Format("{0:f}", 
              (Convert.ToDouble(dgvCarrinhoRow.Cells[3].Value) * Convert.ToDouble(dgvCarrinhoRow.Cells[5].Value))); 

             // Adiciona o valor do produto ao valor total da venda 
             this.totalVenda += Convert.ToDouble(dgvCarrinhoRow.Cells[5].Value); 
            } 
            else if (this.VerificarSeExcede(Convert.ToInt32(dt.Rows[0][0].ToString()), 1) == 0) 
            { 
             MessageBox.Show("Ocorreu a tentativa de vender um produto que está em falta no estoque.", "Caixa", MessageBoxButtons.OK, MessageBoxIcon.Error); 
            } 
            else 
            { 
             MessageBox.Show("Ocorreu a tentativa de vender uma certa quantidade deste produto que excede a quantidade do mesmo no estoque.", "Caixa", MessageBoxButtons.OK, MessageBoxIcon.Error); 
            } 

            itemIgual = true; // Evita que o if abaixo seja executado 
            break; // Sai do loop para econimizar tempo no processamento 
           } 

           rowIndex++; 
          } 

          // Caso o item não seja igual a nenhum outro no carrinho ele é adicionado 
          if (!itemIgual) 
          { 
           // Verifica se estão tentando vender uma certa quantidade de um produto que esteja acima da quantidade do mesmo no estoque 
           if (this.VerificarSeExcede(Convert.ToInt32(dt.Rows[0][0].ToString()), 1) == 1) 
           { 
            this.dataGridViewCarrinho.Rows.Add(
             ++this.item,      // ITEM 
             dt.Rows[0][0], // CÓDIGO 
             dt.Rows[0][3], // DESCRIÇÃO 
             1,       // QTD. 
             dt.Rows[0][2], // UN. 
             dt.Rows[0][3], // VL. UNIT. 
             dt.Rows[0][3]); // VL. ITEM. 

            // Adiciona o valor do produto ao valor total da venda 
            this.totalVenda += Convert.ToDouble(dt.Rows[0][3].ToString()); 
           } 
           else if (this.VerificarSeExcede(Convert.ToInt32(dt.Rows[0][0].ToString()), 1) == 0) 
           { 
            MessageBox.Show("Ocorreu a tentativa de vender um produto que está em falta no estoque.", "Caixa", MessageBoxButtons.OK, MessageBoxIcon.Error); 
           } 
           else 
           { 
            MessageBox.Show("Ocorreu a tentativa de vender uma certa quantidade deste produto que excede a quantidade do mesmo no estoque.", "Caixa", MessageBoxButtons.OK, MessageBoxIcon.Error); 
           } 
          } 

          this.AtualizarValorCompra(); 
          this.dataGridViewCarrinho.ClearSelection(); 
         } 
         else // Mensagem exibida caso a consulta nao retorne alguma coisa 
         { 
          MessageBox.Show("Este item não consta no banco de dados.", "Caixa", MessageBoxButtons.OK, MessageBoxIcon.Error); 
         } 
        } 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show("Ocorreu um erro durante a comunicação com o banco de dados.\n\n" + ex.Message, "Caixa", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       } 
      } 
     } 
    } 

    this.LimparControles(1); 
} 

ответ

6

Там нет установленного предела тому, сколько уровней вложенности вы можете иметь, с или без using, но, конечно, существует практический предел того, насколько вложенности вы можете поместиться на экране, не делая ваши глаза болят. Для этого часто рекомендуется ограничивать вложенность. Вы можете сделать это, наблюдая, что фигурные скобки после составных утверждений являются необязательными. Таким образом, вы можете сделать это:

using (MySqlConnection con = new MySqlConnection(Properties.Settings.Default.ConnectionString)) 
using (MySqlDataAdapter da = new MySqlDataAdapter()) 
using (DataTable dt = new DataTable()) { 
    ... 
} 

Высказывания остаются вложенными друг в друга, как и раньше, но они выглядят как «плоский» на экране.

Одно из ограничений этого подхода заключается в том, что все три переменные (con, da и dt) будут расположены в конце того же объема. Это не проблема в данном конкретном случае, потому что вы заканчиваете все три области без каких-либо операторов между ними (т. Е. В конце у вас есть три закрывающие фигурные скобки). Тем не менее, необходимость ограничить область действия одной из переменных раньше других может заставить вас использовать дополнительный уровень вложенности.

+0

Спасибо за эту информацию, я did't знал, что я мог бы сделать это! – Zignd

+2

+1 для последнего абзаца :) –

2

Я, как правило, сложить их, немного как это:

try 
{ 
    using (var connection = new MySqlConnection(...)) 
    using (var adapter = new MySqlDataAdapter()) 
    using (var table = new DataTable()) 
    using (var cmd = new MySqlCommand(...)) 
    { 
     ... 
    } 
} 

Дело отметить, что объем не должен быть окружен фигурными скобками { } если это только одна команда.

То же самое относится и к foreach и if блоков:

foreach(var x in y) DoSomething(); 
+0

Спасибо за вашу информацию, а также за розничный кодер, но ответ dasblinkenlight выглядит более полным. – Zignd

+0

Нет проблем, здесь я отредактировал, чтобы добавить немного больше мяса; идея заключается в том, что область не привязана к фигурным скобкам, если это только одна инструкция. –

+0

@ Zignd на самом деле вы должны принять ответ dasblinkenlight, он не только более полный, он дает вам фактическую причину, почему/когда вы должны ввести уровень отступов; мой только говорит вам, почему он вам не нужен. –

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