3

IDisposableインターフェイスを自動的に使用してリソースを解放するため、データベースへの接続を開いたり閉じたりする正しい方法はusingステートメントを使用することに気付きました(それ以外の場合は修正してください)。

したがって、私はそれを使用することにしましたが、コードは 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()) {
    ...
}

ステートメントは以前と同じようにネストされたままですが、画面上では「フラット」に見えます。

このアプローチの制限の 1 つは、3 つの変数 ( conda、およびdt) がすべて同じスコープの最後で破棄されることです。これは、この特定のケースでは問題ではありません。間にステートメントを入れずに 3 つのスコープすべてを終了する (つまり、最後に 3 つの右中括弧がある) ためです。ただし、変数の 1 つのスコープを他の変数よりも早く終了する必要がある場合は、追加レベルのネストを使用する必要があります。

于 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(...))
    {
        ...
    }
}

{ }注意すべきことは、スコープが単一の命令のみの場合、スコープを中かっこで囲む必要がないことです。

foreach同じことがandifブロックにも当てはまります。

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