Criar um aplicativo de dados simples usando o ADO.NET

Observação

Os conjuntos de dados e as classes relacionadas são tecnologias herdadas do .NET Framework do início dos anos 2000 que permitem que os aplicativos trabalhem com dados na memória enquanto os aplicativos estão desconectados do banco de dados. Eles são bastante úteis em aplicativos que permitem que os usuários modifiquem dados e persistam as alterações no banco de dados. Embora os conjuntos de dados tenham se mostrado uma tecnologia muito bem-sucedida, é recomendado que os novos aplicativos .NET usem o Entity Framework Core. O Entity Framework proporciona uma forma mais natural de trabalhar com dados tabulares como modelos de objeto e conta com uma interface de programação mais simples.

Ao criar um aplicativo que manipula dados em um banco de dados, você executa tarefas básicas, como definir cadeias de conexão, inserir dados e executar procedimentos armazenados. Seguindo este tópico, você pode descobrir como interagir com um banco de dados de dentro de um aplicativo simples Windows Forms "formulários sobre dados" usando Visual C# ou Visual Basic e ADO.NET. Todas as tecnologias de dados do .NET, incluindo conjuntos de dados, LINQ to SQL e Entity Framework, executam etapas muito semelhantes às mostradas neste artigo.

Este artigo demonstra uma maneira simples de rapidamente obter dados de um banco de dados. Se seu aplicativo precisar modificar os dados de maneiras não triviais e atualizar o banco de dados, considere usar o Entity Framework e usar a associação de dados para sincronizar automaticamente os controles de interface do usuário com as alterações nos dados subjacentes.

Importante

Para manter o código simples, ele não inclui o tratamento de exceção pronto para produção.

Observação

O código completo deste tutorial pode ser acessado no repositório GitHub de documentos do Visual Studio em C# e Visual Basic.

Pré-requisitos

Para criar o aplicativo, você precisará de:

  • Visual Studio com as cargas de trabalho do desenvolvimento do .NET para desktop e do armazenamento e processamento de dados instaladas. Para instalá-las, abra Instalador do Visual Studio e escolha Modificar (ou Mais>Modificar) ao lado da versão do Visual Studio que você deseja modificar.

  • LocalDB do SQL Server Express. Se você não tiver SQL Server Express LocalDB, poderá instalá-lo na página de download do SQL Server.

Este tópico pressupõe que você esteja familiarizado com a funcionalidade básica do IDE do Visual Studio e possa criar um aplicativo Windows Forms, adicionar formulários ao projeto, colocar botões e outros controles nos formulários, definir propriedades dos controles e codificar eventos simples. Se você não estiver confortável com essas tarefas, sugerimos que conclua o tutorial Criar um aplicativo Windows Forms no Visual Studio com o Visual Basic ou o tutorial Criar um aplicativo Windows Forms no Visual Studio com C# antes de iniciar este passo a passo.

Configurar o banco de dados de exemplo

Crie o banco de dados de exemplo seguindo estas etapas:

  1. No Visual Studio, abra a janela Gerenciador de Servidores.

  2. Clique com o botão direito do mouse em Conexões de Dados e escolha Criar Banco de Dados SQL Server.

  3. Na caixa de texto Nome do servidor, insira (localdb)\mssqllocaldb.

  4. Na caixa de texto Novo nome do banco de dados, insira Vendas e escolha OK.

    O banco de dados de Vendas vazio é criado e adicionado ao nó Conexões de Dados no Gerenciador de Servidores.

  5. Clique com o botão direito do mouse na conexão de dados de Vendas e selecione Nova Consulta.

    Uma janela do editor de consultas vai se abrir.

  6. Copie o script Transact-SQL de Vendas para a sua área de transferência.

  7. Cole o script T-SQL no editor de consultas e escolha o botão Executar.

    Após um curto período de tempo, a consulta termina de ser executada e os objetos do banco de dados são criados. O banco de dados contém duas tabelas: Cliente e Pedidos. Inicialmente, essas tabelas não contêm dados, mas você pode adicionar dados ao executar o aplicativo que você criará. O banco de dados também contém quatro procedimentos armazenados simples.

Criar os formulários e adicionar controles

  1. Crie um projeto C# ou Visual Basic usando o modelo do Windows Forms App (.NET Framework) e nomeie-o SimpleDataApp.

    O Visual Studio cria o projeto e vários arquivos, incluindo um formulário vazio do Windows chamado Form1.

  2. Adicione dois formulários do Windows ao seu projeto para que ele tenha três formulários e dê a eles os seguintes nomes:

    • Navegação

    • NewCustomer

    • FillOrCancel

  3. Para cada formulário, adicione as caixas de texto, botões e outros controles que aparecem nas ilustrações a seguir. Para cada controle, defina as propriedades que as tabelas descrevem.

    Observação

    A caixa de grupo e os controles de rótulo adicionam clareza, mas não são usados no código.

    Formulário Navegação

    Caixa de diálogo Navegação

Controles para o formulário Navegação Propriedades
Botão Nome = btnGoToAdd
Botão Nome = btnGoToFillOrCancel
Botão Nome = btnExit

Formulário NewCustomer

Adicionar um novo cliente e fazer um pedido

Controles para o formulário NewCustomer Propriedades
TextBox Nome = txtCustomerName
TextBox Nome = txtCustomerID

ReadOnly = True
Botão Nome = btnCreateAccount
NumericUpdown DecimalPlaces = 0

Máximo = 5.000

Nome = numOrderAmount
DateTimePicker Formato = Curto

Nome = dtpOrderDate
Botão Nome = btnPlaceOrder
Botão Nome = btnAddAnotherAccount
Botão Nome = btnAddFinish

Formulário FillOrCancel

preencher ou cancelar pedidos

Controles para o formulário FillOrCancel Propriedades
TextBox Nome = txtOrderID
Botão Nome = btnFindByOrderID
DateTimePicker Formato = Curto

Nome = dtpFillDate
DataGridView Nome = dgvCustomerOrders

ReadOnly = True

RowHeadersVisible = False
Botão Nome = btnCancelOrder
Botão Nome = btnFillOrder
Botão Nome = btnFinishUpdates

Armazenar a cadeia de conexão

Quando seu aplicativo tenta abrir uma conexão com o banco de dados, seu aplicativo deve ter acesso à cadeia de conexão. Para evitar inserir a cadeia de caracteres manualmente em cada formulário, armazene a cadeia de caracteres no arquivo App.config em seu projeto e crie um método que retorna a cadeia de caracteres quando o método é chamado de qualquer formulário em seu aplicativo.

Você pode encontrar a cadeia de conexão clicando com o botão direito do mouse na conexão de dados de Vendas no Gerenciador de Servidores e escolhendo Propriedades. Localize a propriedade ConnectionString e use Ctrl+A, Ctrl+C para selecionar e copiar a cadeia de caracteres para a área de transferência.

  1. Se você estiver usando C#, no Gerenciador de Soluções, expanda o nó Propriedades no projeto e abra o arquivo Settings.settings. Se você estiver usando o Visual Basic, no Gerenciador de Soluções, clique em Mostrar Todos os Arquivos, expanda o nó Meu Projeto e abra o arquivo Settings.settings.

  2. Na coluna Nome, insira connString.

  3. Na lista Tipo, selecione (Cadeia de Conexão).

  4. Na lista Escopo, selecione Aplicativo.

  5. Na coluna Valor, insira a cadeia de conexão (sem aspas externas) e salve as alterações.

    Captura de tela de Cadeia de Conexão em Settings.settings

Observação

Em um aplicativo real, você deve armazenar a cadeia de conexão com segurança, conforme descrito em Cadeias de conexão e arquivos de configuração.

Escrever o código para os formulários

Esta seção contém breves visões gerais do que cada formulário faz. Ela também fornece o código que define a lógica subjacente quando um botão no formulário é clicado.

O formulário Navegação é aberto quando você executa o aplicativo. O botão Adicionar uma conta abre o formulário NewCustomer. O botão Preencher ou cancelar pedidos abre o formulário FillOrCancel. O botão Sair fecha o aplicativo.

Tornar o formulário Navegação o formulário de inicialização

Se você estiver usando C#, no Gerenciador de Soluções, abra Program.cs e altere a linha Application.Run para esta: Application.Run(new Navigation());

Se você estiver usando o Visual Basic, no Gerenciador de Soluções, abra a janela Propriedades, selecione a guia Aplicativo e selecione SimpleDataApp.Navigation na lista Formulário de inicialização.

Criar manipuladores de eventos gerados automaticamente

Clique duas vezes nos três botões no formulário Navegação para criar métodos vazios do manipulador de eventos. Clicar duas vezes nos botões também adiciona o código gerado automaticamente no arquivo de código do Designer que permite um clique de botão para gerar um evento.

Observação

Se você ignorar a ação de clique duplo no designer e apenas copiar o código e colá-lo em seus arquivos de código, não se esqueça de definir o manipulador de eventos para o método correto. Você pode fazer isso na janela Propriedades. Alterne para a guia Eventos (use o botão de raio da barra de ferramentas) e procure o manipulador Clique.

Adicionar código para a lógica do formulário Navegação

Na página de código do formulário Navegação, conclua os corpos do método dos manipuladores de eventos de clique de três botões, conforme mostrado no código a seguir.

/// <summary>
/// Opens the NewCustomer form as a dialog box,
/// which returns focus to the calling form when it is closed. 
/// </summary>
private void btnGoToAdd_Click(object sender, EventArgs e)
{
    Form frm = new NewCustomer();
    frm.Show();
}

/// <summary>
/// Opens the FillorCancel form as a dialog box. 
/// </summary>
private void btnGoToFillOrCancel_Click(object sender, EventArgs e)
{
    Form frm = new FillOrCancel();
    frm.ShowDialog();
}

/// <summary>
/// Closes the application (not just the Navigation form).
/// </summary>
private void btnExit_Click(object sender, EventArgs e)
{
    this.Close();
}

Observação

O código deste tutorial está disponível em C# e Visual Basic. Para alternar o idioma de código nesta página entre C# e Visual Basic, use o comutador de idioma de código na parte superior de cada exemplo de código.

Formulário NewCustomer

Quando você insere um nome de cliente e seleciona o botão Criar Conta, o formulário NewCustomer cria uma conta de cliente e o SQL Server retorna um valor IDENTITY como a nova ID do cliente. Em seguida, você pode fazer um pedido para a nova conta especificando um valor e uma data de pedido e selecionando o botão Fazer Pedido.

Criar manipuladores de eventos gerados automaticamente

Crie um manipulador de eventos Clique vazio para cada botão no formulário NewCustomer clicando duas vezes em cada um dos quatro botões. Clicar duas vezes nos botões também adiciona o código gerado automaticamente no arquivo de código do Designer que permite um clique de botão para gerar um evento.

Adicionar código para a lógica do formulário NewCustomer

Para concluir a lógica do formulário NewCustomer, siga estas etapas.

  1. Traga o namespace System.Data.SqlClient para o escopo para que você não precise qualificar totalmente os nomes de seus membros.

    using System.Data.SqlClient;
    
  2. Adicione algumas variáveis e métodos auxiliares à classe, conforme mostrado no código a seguir.

    // Storage for IDENTITY values returned from database.
    private int parsedCustomerID;
    private int orderID;
    
    /// <summary>
    /// Verifies that the customer name text box is not empty.
    /// </summary>
    private bool IsCustomerNameValid()
    {
        if (txtCustomerName.Text == "")
        {
            MessageBox.Show("Please enter a name.");
            return false;
        }
        else
        {
            return true;
        }
    }
    
    /// <summary>
    /// Verifies that a customer ID and order amount have been provided.
    /// </summary>
    private bool IsOrderDataValid()
    {
        // Verify that CustomerID is present.
        if (txtCustomerID.Text == "")
        {
            MessageBox.Show("Please create customer account before placing order.");
            return false;
        }
        // Verify that Amount isn't 0.
        else if ((numOrderAmount.Value < 1))
        {
            MessageBox.Show("Please specify an order amount.");
            return false;
        }
        else
        {
            // Order can be submitted.
            return true;
        }
    }
    
    /// <summary>
    /// Clears the form data.
    /// </summary>
    private void ClearForm()
    {
        txtCustomerName.Clear();
        txtCustomerID.Clear();
        dtpOrderDate.Value = DateTime.Now;
        numOrderAmount.Value = 0;
        this.parsedCustomerID = 0;
    }
    
  3. Conclua os corpos do método para os quatro manipuladores de eventos de clique com botão, conforme mostrado no código a seguir.

    /// <summary>
    /// Creates a new customer by calling the Sales.uspNewCustomer stored procedure.
    /// </summary>
    private void btnCreateAccount_Click(object sender, EventArgs e)
    {
        if (IsCustomerNameValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create a SqlCommand, and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspNewCustomer", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add input parameter for the stored procedure and specify what to use as its value.
                    sqlCommand.Parameters.Add(new SqlParameter("@CustomerName", SqlDbType.NVarChar, 40));
                    sqlCommand.Parameters["@CustomerName"].Value = txtCustomerName.Text;
    
                    // Add the output parameter.
                    sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int));
                    sqlCommand.Parameters["@CustomerID"].Direction = ParameterDirection.Output;
    
                    try
                    {
                        connection.Open();
    
                        // Run the stored procedure.
                        sqlCommand.ExecuteNonQuery();
    
                        // Customer ID is an IDENTITY value from the database.
                        this.parsedCustomerID = (int)sqlCommand.Parameters["@CustomerID"].Value;
    
                        // Put the Customer ID value into the read-only text box.
                        this.txtCustomerID.Text = Convert.ToString(parsedCustomerID);
                    }
                    catch
                    {
                        MessageBox.Show("Customer ID was not returned. Account could not be created.");
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Calls the Sales.uspPlaceNewOrder stored procedure to place an order.
    /// </summary>
    private void btnPlaceOrder_Click(object sender, EventArgs e)
    {
        // Ensure the required input is present.
        if (IsOrderDataValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create SqlCommand and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspPlaceNewOrder", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add the @CustomerID input parameter, which was obtained from uspNewCustomer.
                    sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int));
                    sqlCommand.Parameters["@CustomerID"].Value = this.parsedCustomerID;
    
                    // Add the @OrderDate input parameter.
                    sqlCommand.Parameters.Add(new SqlParameter("@OrderDate", SqlDbType.DateTime, 8));
                    sqlCommand.Parameters["@OrderDate"].Value = dtpOrderDate.Value;
    
                    // Add the @Amount order amount input parameter.
                    sqlCommand.Parameters.Add(new SqlParameter("@Amount", SqlDbType.Int));
                    sqlCommand.Parameters["@Amount"].Value = numOrderAmount.Value;
    
                    // Add the @Status order status input parameter.
                    // For a new order, the status is always O (open).
                    sqlCommand.Parameters.Add(new SqlParameter("@Status", SqlDbType.Char, 1));
                    sqlCommand.Parameters["@Status"].Value = "O";
    
                    // Add the return value for the stored procedure, which is  the order ID.
                    sqlCommand.Parameters.Add(new SqlParameter("@RC", SqlDbType.Int));
                    sqlCommand.Parameters["@RC"].Direction = ParameterDirection.ReturnValue;
    
                    try
                    {
                        //Open connection.
                        connection.Open();
    
                        // Run the stored procedure.
                        sqlCommand.ExecuteNonQuery();
    
                        // Display the order number.
                        this.orderID = (int)sqlCommand.Parameters["@RC"].Value;
                        MessageBox.Show("Order number " + this.orderID + " has been submitted.");
                    }
                    catch
                    {
                        MessageBox.Show("Order could not be placed.");
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Clears the form data so another new account can be created.
    /// </summary>
    private void btnAddAnotherAccount_Click(object sender, EventArgs e)
    {
        this.ClearForm();
    }
    
    /// <summary>
    /// Closes the form/dialog box.
    /// </summary>
    private void btnAddFinish_Click(object sender, EventArgs e)
    {
        this.Close();
    }
    

Formulário FillOrCancel

O formulário FillOrCancel executa uma consulta para retornar um pedido quando você insere uma ID de pedido e clica no botão Localizar Pedido. A linha retornada aparece em uma grade de dados somente leitura. Você pode marcar o pedido como cancelado (X) se selecionar o botão Cancelar Pedido ou marcar o pedido como preenchido (F) se selecionar o botão Preencher Pedido. Se você selecionar o botão Localizar Pedido novamente, a linha atualizada será exibida.

Criar manipuladores de eventos gerados automaticamente

Crie manipuladores de eventos Clique vazios para os quatro botões no formulário FillOrCancel clicando duas vezes nos botões. Clicar duas vezes nos botões também adiciona o código gerado automaticamente no arquivo de código do Designer que permite um clique de botão para gerar um evento.

Adicionar código para a lógica do formulário FillOrCancel

Para concluir a lógica do formulário FillOrCancel, siga estas etapas.

  1. Traga os dois namespaces a seguir para o escopo para que você não precise qualificar totalmente os nomes de seus membros.

    using System.Data.SqlClient;
    using System.Text.RegularExpressions;
    
  2. Adicione uma variável e um método auxiliar à classe, conforme mostrado no código a seguir.

    // Storage for the order ID value.
    private int parsedOrderID;
    
    /// <summary>
    /// Verifies that an order ID is present and contains valid characters.
    /// </summary>
    private bool IsOrderIDValid()
    {
        // Check for input in the Order ID text box.
        if (txtOrderID.Text == "")
        {
            MessageBox.Show("Please specify the Order ID.");
            return false;
        }
    
        // Check for characters other than integers.
        else if (Regex.IsMatch(txtOrderID.Text, @"^\D*$"))
        {
            // Show message and clear input.
            MessageBox.Show("Customer ID must contain only numbers.");
            txtOrderID.Clear();
            return false;
        }
        else
        {
            // Convert the text in the text box to an integer to send to the database.
            parsedOrderID = Int32.Parse(txtOrderID.Text);
            return true;
        }
    }
    
  3. Conclua os corpos do método para os quatro manipuladores de eventos de clique com botão, conforme mostrado no código a seguir.

    /// <summary>
    /// Executes a t-SQL SELECT statement to obtain order data for a specified
    /// order ID, then displays it in the DataGridView on the form.
    /// </summary>
    private void btnFindByOrderID_Click(object sender, EventArgs e)
    {
        if (IsOrderIDValid())
        {
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Define a t-SQL query string that has a parameter for orderID.
                const string sql = "SELECT * FROM Sales.Orders WHERE orderID = @orderID";
    
                // Create a SqlCommand object.
                using (SqlCommand sqlCommand = new SqlCommand(sql, connection))
                {
                    // Define the @orderID parameter and set its value.
                    sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int));
                    sqlCommand.Parameters["@orderID"].Value = parsedOrderID;
    
                    try
                    {
                        connection.Open();
    
                        // Run the query by calling ExecuteReader().
                        using (SqlDataReader dataReader = sqlCommand.ExecuteReader())
                        {
                            // Create a data table to hold the retrieved data.
                            DataTable dataTable = new DataTable();
    
                            // Load the data from SqlDataReader into the data table.
                            dataTable.Load(dataReader);
    
                            // Display the data from the data table in the data grid view.
                            this.dgvCustomerOrders.DataSource = dataTable;
    
                            // Close the SqlDataReader.
                            dataReader.Close();
                        }
                    }
                    catch
                    {
                        MessageBox.Show("The requested order could not be loaded into the form.");
                    }
                    finally
                    {
                        // Close the connection.
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Cancels an order by calling the Sales.uspCancelOrder
    /// stored procedure on the database.
    /// </summary>
    private void btnCancelOrder_Click(object sender, EventArgs e)
    {
        if (IsOrderIDValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create the SqlCommand object and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspCancelOrder", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add the order ID input parameter for the stored procedure.
                    sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int));
                    sqlCommand.Parameters["@orderID"].Value = parsedOrderID;
    
                    try
                    {
                        // Open the connection.
                        connection.Open();
    
                        // Run the command to execute the stored procedure.
                        sqlCommand.ExecuteNonQuery();
                    }
                    catch
                    {
                        MessageBox.Show("The cancel operation was not completed.");
                    }
                    finally
                    {
                        // Close connection.
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Fills an order by calling the Sales.uspFillOrder stored
    /// procedure on the database.
    /// </summary>
    private void btnFillOrder_Click(object sender, EventArgs e)
    {
        if (IsOrderIDValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create command and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspFillOrder", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add the order ID input parameter for the stored procedure.
                    sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int));
                    sqlCommand.Parameters["@orderID"].Value = parsedOrderID;
    
                    // Add the filled date input parameter for the stored procedure.
                    sqlCommand.Parameters.Add(new SqlParameter("@FilledDate", SqlDbType.DateTime, 8));
                    sqlCommand.Parameters["@FilledDate"].Value = dtpFillDate.Value;
    
                    try
                    {
                        connection.Open();
    
                        // Execute the stored procedure.
                        sqlCommand.ExecuteNonQuery();
                    }
                    catch
                    {
                        MessageBox.Show("The fill operation was not completed.");
                    }
                    finally
                    {
                        // Close the connection.
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Closes the form.
    /// </summary>
    private void btnFinishUpdates_Click(object sender, EventArgs e)
    {
        this.Close();
    }
    

Teste seu aplicativo

Execute o aplicativo e tente criar alguns clientes e pedidos para verificar se tudo está funcionando conforme esperado. Para verificar se o banco de dados foi atualizado com suas alterações, abra o nó Tabelas no Gerenciador de Servidores, clique com o botão direito do mouse nos nós Clientes e Pedidos e escolha Mostrar Dados da Tabela.