3

我注意到打开和关闭与数据库的连接的正确方法是使用 using语句,因为它会自动使用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);
}
4

2 回答 2

8

嵌套的层数没有设置限制,不管有没有using,但当然,在不伤害眼睛的情况下,你可以在屏幕上放置多少嵌套是有实际限制的。为此,限制嵌套通常是个好主意。您可以通过观察复合语句后的花括号是可选的来做到这一点。因此,您可以这样做:

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

语句仍然像以前一样相互嵌套,但它们在屏幕上看起来“扁平”。

这种方法的一个限制是所有三个变量(condadt)都将被放置在同一范围的末尾。在这种特殊情况下,这不是问题,因为您结束了所有三个作用域,中间没有任何语句(即,最后有三个右大括号)。但是,需要比其他变量更早结束其中一个变量的范围可能会迫使您使用额外的嵌套级别。

于 2013-05-17T00:23:31.173 回答
2

我倾向于将它们堆叠起来,有点像这样:

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

{ }需要注意的是,如果它只是一条指令,则范围不需要用大括号括起来。

这同样适用于foreachif块:

foreach(var x in y) DoSomething();
于 2013-05-17T00:23:41.820 回答