A busca de aplicativos que visam uma maior velocidade no processamento em conjunto com um eficiente e eficaz desempenho propicia a criação de novas metodologias para satisfazer tanto o sistema quanto o usuário que vai interagir com a aplicação. Com isso, o desenvolvimento de stored procedures dentro do banco de dados aperfeiçoa esses requisitos, atendendo as necessidades para essa mentalidade de implementação em sistemas que utilizam a linguagem de programação C#.
Criando o Sistema
Neste artigo vamos criar um projeto para que o usuário faça um cadastro de clientes e busque os mesmos através de uma pesquisa por nome ou CPF. Além disso, será possível alterar ou excluir o registro. Então o primeiro passo para a criação do sistema é abrir o Visual Studio e ir para a barra de menus, File → New → Project. Aparecerá uma janela denominada New Project, e nela você deve inserir as mesmas informações presentes na Figura 1: o Name será CSharpComSQLServer, Location será no disco D:\ e o Solution name será o mesmo do Name. Com tudo configurado, é só clicar em OK que a estrutura do projeto será criada.
Figura 1. Tela de configuração para a criação de um novo projeto Windows Forms Application.
Criando o Banco de Dados
Dentro do projeto será criado um novo banco de dados (SQL Server), cuja finalidade é interagir com o sistema. Para isso, com o projeto criado, na parte Solution Explorer clique com o botão direito sobre o nome do projeto e vá para o caminho: Add → New Item. Selecione a opção Service-based Database, como mostra a Figura 2.
Figura 2. Configurando novo banco de dados interno, cujo nome é Dados.mdf.
Aparecerá uma nova janela e nela selecione a opção Dataset. Clique em Next e em seguida vai aparecer uma janela para definição do nome para um DataSet a ser criado que, por padrão, este será o mesmo dado automaticamente DadosDataSet e finalmente clique em Finish.
O procedimento a seguir é para criar uma nova tabela dentro do banco de dados. Para isso, basta ir ao Solution Explorereclique com o botão direito em cima de Dados.mdf e depois em Open. Na parte lateral esquerda vai aparecer o banco de dados criado já conectado. Para a tabela Clientes, clique com o botão direito em cima de Tables (localizado em Server Explorer) e depois em Add New Table. Assim, a estrutura da nova tabela estará pronta para a criação de seus campos, propriedades, tamanho, dentre outras opções. Configure de acordo com a Figura 3.
Figura 3. Column Name (nome dos campos), Data Type (tipo dos dados e tamanhos) e Allow Nulls (se estiver marcado, permite nulo).
Observação: o campo CPF, por ser chave primária, foi preciso clicar com o botão direito em cima do campo e depois em Set Primary Key. Esse campo não precisa ser auto incremento.
Agora vamos a criação das Stored Procedures: serão cinco e cada um responsável por realizar um comportamento diferente. O procedimento para a criação é clicar com o botão direito em Stored Procedures do banco de dados Dados.mdf (localizado em Server Explorer), e clicar em Add New Stored Procedure para criar o esqueleto para futura programação.
A primeira a ser criada será abuscaCliCPF e terá finalidade de busca do cliente por CPF, de acordo com a Listagem 1.
Listagem 1. Busca dos dados do cliente de acordo com o CPF informado pelo usuário.
CREATE PROCEDURE dbo.buscaCliCPF
@CPF varchar(15)
AS
Select cpf, nome, endereco, telefone
from clientes
where CPF=@CPF
A próxima a ser criada será com o nome de buscaCliNome e terá a finalidade de buscar o cliente pelo Nome, de acordo com o que mostra a Listagem 2.
Listagem 2. Busca dos dados do cliente de acordo com o nome informado pelo usuário.
ALTER PROCEDURE dbo.buscaCliNome
@nome varchar(50)
AS
select cpf, nome, endereco, telefone
from clientes
where nome like @nome +'%'
A outra SP vai buscar todos os clientes cadastrados e terá o nome de buscaTodos, a serimplementada de acordo com o que mostra a Listagem 3.
Listagem 3. Faz uma busca de todos os clientes cadastrados.
CREATE PROCEDURE dbo.buscaTodos
AS
Select cpf, nome, endereco, telefone
from clientes
Agora será criado uma SP com o nome de ExcluirCliente e que tem a finalidade de exclusão do cliente, como demonstra a Listagem 4.
Listagem 4. Stored Procedure responsável por excluir um cliente de acordo com o CPF informado pelo usuário.
CREATE PROCEDURE dbo.ExcluirCliente
@CPF varchar(15)
AS
delete from clientes where cpf = @cpf
E finalizando, será criado uma Stored Procedure com o nome inserir_alterar_Cliente e sua finalidade é para a inclusão e alteração do cliente, de acordo com a Listagem 5. As mudanças ocorrerão de acordo com uma espécie de sinalizador a ser informado durante a implementação do projeto futuramente. Se for igual a 1, será executada a instrução para inserção, senão será executada a instrução para alteração de acordo com o CPF informado.
Listagem 5. Código responsável por fazer a inserção do cliente ou a alteração
CREATE PROCEDURE dbo.inserir_alterar_Cliente
@CPF varchar(15),
@nome varchar(50),
@endereco varchar (100),
@telefone varchar(15),
@flag int
AS
if (@flag = 1)
begin
insert into Clientes(cpf,nome,endereco,telefone)
values(@CPF,@nome,@endereco,@telefone)
end
else begin
update clientes
set nome = @nome, endereco = @endereco, telefone = @telefone
where cpf = @cpf
end
Configurando o Arquivo Dataset
Ao criar um novo banco de dados, foi definido um nome do DataSet para DadosDataSet. A partir de agora ele será manipulado para resgatar valores e enviar informações sendo um intermediário entre a aplicação e o banco de dados. Ele cria em memória uma replicação do banco de dados físico.
Para manipular este arquivo, basta dar duplo clique sobre ele e, após aberto, clicar com o botão direito sobre a parte listada do arquivo e seguir com o caminho: Add → TableAdapter. Vai aparecer uma janela com o nome TableAdapter Configuration Wizard.Clicando em Next, selecione a opçãoUse SQL Statements e clique em Next novamente. Aparecerá uma janela de acordo com a Figura 4, só que sem a instrução SQL.
Figura 4. Tela de entrada para instrução SQL.
Depois de colocada essa instrução, ficará responsável por trazer todas as informações de acordo com a tabela Clientes.
Clicando em Next, vai aparecer a janela igual a da Figura 5.
Figura 5. Janela de configuração de métodos de envio e retorno de dados para DataTable.
Para finalizar, é só clicar em Finish. Então será criado um modelo contendo a tabela Clientes (com seus respectivos campos) e o ClientesTableAdapter contendo os métodos Fill e Get.
O procedimento a seguir é trazer as Stored Procedures criadas para o DadosDataSete para isso,clique com o botão direito em ClientesTableAdapter->AddQuery.
Aparecerá uma janela com a opção Use Existing Stored Procedure, então selecione a Stored Procedure buscaCliCPF e clique em Next. Como é uma busca de dados, então agora será selecionada a opção Tabular data – Fill/Get methods will be generated to return tabular data from the stored procedure.
Uma nova janela será aberta, parecida com a Figura 5. Nela desmarque a opção Return a DataTable e na opção Method name do Fill a DataTable coloque o nome para essa propriedade, que será FillByBuscaCliCPF.
O mesmo procedimento será efetuado para as SPs buscaCliNome e buscaTodos, porém para a primeiro informada, no Method name do Fill a DataTable será FillByBuscaCliNome e para a segunda será FillByDados.
Agora para as SPs ExcluirCliente e inserir_alterar_Cliente serão efetuados os mesmos caminhos, só que ao invés de ser Tabular data – Fill/Get methods will be generated to return tabular data from the stored procedure, será com a propriedade No value – A typed method will be generated to execute a stored procedure which doesn’t return data.
Os nomes das propriedades serão idênticas ao nome das SPs. Após ter criado todas as propriedades, deve ficar semelhante a Figura 6.
Figura 6. DadosDataSet.xsd devidamente configurado. Salve todo o arquivo com as operações feitas.
Desenvolvendo a aplicação
Dentro do Solution Explorer ficaram definidos alguns arquivos criados automaticamente e manualmente, dentro de uma estrutura semelhante a da Figura 7.
Figura 7. Estrutura dos arquivos criados até o momento.
Inicialmente, no arquivo Form1.cs vamos alterar o seu nome para frmPrincipal.cs. Após isso, ao dar duplo clique nele, vai aparecer um formulário simples para colocar um componente de menus na barra superior chamado MenuStrip, localizado no ToolBox (geralmente localizado na parte esquerda) na aba Menus & Toolbars.
Após ter adicionado o MenuStrip, vamos colocar os submenus, bastando selecionar o menu superior, clicar em Type Here e colocar um nome para o menu, que será de Cadastro.
Para adicionar submenus, basta clicar em cima do menu criado e em baixo clicar em Type Here. Será preciso criar dois submenus: o primeiro com o nome Clientes e o segundo com o nome Sair.
Dica: Para colocar um título para um menu ou submenu, basta ir em Properties (geralmente localizado na parte direita e abaixo do Solution Explorer), procurar pela propriedade Text e alterar seu nome.
Para excluir um menu ou submenu, basta clicar sobre qualquer um e apertar a tecla delete.
Agora será configurado o formulário, que se baseará de acordo com a particularidade Properties e ficará de acordo com a Tabela 1.
Nome da propriedade |
Como ficará definido |
Name |
frmPrincipal |
AutoScaleMode |
Font |
ForeColor |
ControlText |
IsMdiContainer |
True |
Text |
Projeto |
WindowsState |
Maximized |
Tabela 1. Tabela contendo os nomes das propriedades do formulário e como ficará definida cada uma delas.
Após as configurações feitas, a tela principal (inicial) ficará de acordo com a Figura 8.
Figura 8. Tela inicial configurada com menu Cadastro e submenus Clientes e Sair.
O procedimento a seguir é criar dois formulários do Windows Form, um para o cadastro de clientes e outro para a pesquisa. Para criar um formulário, clique com o botão direito sobre o projeto (no Solution Explorer) e siga o caminho Add → Windows Form. Abrirá uma janela para o formulário frmCliente.cs. Esse processo será repetido mais uma vez, porém o nome deste outro formulário será frmPesquisaCliente.cs.
Em seguida será criada uma classe para validações de CPF e para adicioná-la, clique com o botão direito sobre o projeto e siga o caminho Add → Classcom o nome Validacoes.cs. Para ter uma ideia, a estrutura dos arquivos criados no projeto, localizados no Solution Explorer, deve ficar semelhante ao que mostra a Figura 9.
Figura 9. Solution Explorer com seus arquivos.
Dentro da classe Validacoes.cs será implementada os códigos descritos na Listagem 6.
Listagem 6. Classe para validação do CPF.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CSharpComSQLServer
{
public class Validacoes
{
public static bool validarCPF(string cpf)
{
string valor = cpf.Replace(".", "");
valor = valor.Replace("-", "");
if (valor.Length != 11)
return false;
bool igual = true;
for (int i = 1; i < 11 && igual; i++)
if (valor[i] != valor[0])
igual = false;
if (igual || valor == "12345678909")
return false;
int[] numeros = new int[11];
for (int i = 0; i < 11; i++)
numeros[i] = int.Parse(valor[i].ToString());
int soma = 0;
for (int i = 0; i < 9; i++)
soma += (10 - i) * numeros[i];
int resultado = soma % 11;
if (resultado == 1 || resultado == 0)
{
if (numeros[9] != 0)
return false;
}
else if (numeros[9] != 11 - resultado)
return false;
soma = 0;
for (int i = 0; i < 10; i++)
soma += (11 - i) * numeros[i];
resultado = soma % 11;
if (resultado == 1 || resultado == 0)
{
if (numeros[10] != 0)
return false;
}
else
if (numeros[10] != 11 - resultado)
return false;
return true;
}
}
}
Formulário para Cadastro de Clientes
Agora definiremos o que será exibido para o usuário para que ele faça as operações de acordo com a tela de cadastro de clientes. No formulário frmCliente.cs será configurada as Properties e também serão adicionados Buttons, Labels, TextBoxs e MaskedTextBoxs na tela, que ficarão de acordo com a Tabela 2.
Nome da propriedade do Form |
Como ficará definido |
|
Name |
frmCliente |
|
AutoScaleMode |
Font |
|
MaximizedBox |
False |
|
StartPosition |
CenterScreen |
|
Text |
Cadastro de Clientes |
|
Nome do componente |
Nome da propriedade |
Como ficará definido |
Label |
Text |
CPF: |
Label |
Text |
Nome: |
Label |
Text |
Endereço: |
Label |
Text |
Telefone: |
MasketTextBox |
Name |
mskCPF |
Mask |
999,999,999-99 |
|
Modifiers |
Public |
|
TextBox |
Name |
txtNome |
Modifiers |
Public |
|
TextBox |
Name |
txtEndereco |
Modifiers |
Public |
|
MasketTextBox |
Name |
mskTelefone |
Mask |
(99)0000-0000 |
|
Modifiers |
Public |
|
Button |
Name |
btnLLocalizar |
Text |
Pesquisar ... |
|
Button |
Name |
btnIncluir |
Text |
Incluir |
|
Button |
Name |
btnAlterar |
Modifiers |
Public |
|
Button |
Text |
Alterar |
Name |
btnExcluir |
|
Button |
Modifiers |
Public |
Text |
Excluir |
|
Button |
Name |
btnFechar |
Text |
Fechar |
Tabela 2. Tela de Cadastro de Clientes com seus componentes e suas respectivas configurações a serem colocadas no formulário.
Para ter uma ideia, o layout dos componentes na tela poderá ficar da forma como ilustra a Figura 10.
Figura 10. Arquivo frmCliente.cs no modo Design ilustrando os componentes na tela.
Ao apertar a tecla F7 ou clicar com o botão direito sobre o formulário e ir em View Code, acrescente os códigos descritos na Listagem 7.
Listagem 7. Códigos a serem implementados no formulário de cadastro de clientes.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace CSharpComSQLServer
{
public partial class frmCliente : Form
{
DadosDataSetTableAdapters.ClientesTableAdapter TAClientes = new DadosDataSetTableAdapters.ClientesTableAdapter();
frmPrincipal Pri;
public frmCliente()
{
InitializeComponent();
}
public frmCliente(frmPrincipal formularioPri)
{
InitializeComponent();
Pri = formularioPri;
}
private void frmCliente_Load(object sender, EventArgs e)
{
if (mskCPF.Text != "")
{
btnAlterar.Enabled = false;
btnExcluir.Enabled = false;
}
}
private void btnLLocalizar_Click(object sender, EventArgs e)
{
frmPesquisaCliente frmPesqCli = new frmPesquisaCliente(this);
frmPesqCli.ShowDialog(this);
}
private void btnIncluir_Click(object sender, EventArgs e)
{
mskCPF.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals;
if (mskCPF.Text == "")
MessageBox.Show("Informe um CPF!", "CPF", MessageBoxButtons.OK, MessageBoxIcon.Error);
else
{
if (Validacoes.validarCPF(mskCPF.Text))
{
mskCPF.TextMaskFormat = MaskFormat.IncludePromptAndLiterals;
try
{
TAClientes.inserir_alterar_Cliente(mskCPF.Text, txtNome.Text, txtEndereco.Text, mskTelefone.Text, 1);
MessageBox.Show("Cliente cadastrado com sucesso!", "Clientes", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show("Erro ao inserir Cliente\n" + ex.Message, "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
MessageBox.Show("Informe um CPF válido!", "CPF", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnAlterar_Click(object sender, EventArgs e)
{
try
{
TAClientes.inserir_alterar_Cliente(mskCPF.Text, txtNome.Text, txtEndereco.Text, mskTelefone.Text, 2);
MessageBox.Show("Dados atualizados!", "Clientes", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show("Erro ao atualizar Cliente\n" + ex.Message, "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnExcluir_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Deseja realmente excluir este cliente?", "Excluir cliente", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
TAClientes.ExcluirCliente(mskCPF.Text);
mskCPF.Text = "";
mskTelefone.Text = "";
txtEndereco.Text = "";
txtNome.Text = "";
MessageBox.Show("Cliente excluído", "Confirmação de Exclusão", MessageBoxButtons.OK, MessageBoxIcon.Information);
btnExcluir.Enabled = false;
btnAlterar.Enabled = false;
}
catch (Exception ex)
{
MessageBox.Show("Falha ao excluir cliente!\n" + ex.Message, "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void btnFechar_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Veja que inicialmente é colocada a importação using System.Text.RegularExpressions, responsável por controlar a expressão regular durante o controle de máscara para o CPF. Em seguida é instanciado o TAClientes do tipo DadosDataSetTableAdapters.ClientesTableAdapter, que é responsável por controlar as alterações do DataSetTableAdapters dos Clientes criados no arquivo DadosDataSet.
Além disso, é criada uma variável do tipo frmPrincipal e seu construtor para que esse formulário seja “filho” e que o resto da aplicação não possa ser manipulada quando esse estiver aberta.
Quando o formulário é iniciado (Load) os botões de alterar e excluir são desabilitados.
No botão Pesquisar é colocado o método btnLLocalizar_Click que chama o formulário de pesquisa de clientes.
No botão Incluir é colocado o método btnIncluir_Click, criando uma condição para verificar se o CPF foi informado e outra condição para verificar se o CPF informado é válido. Se estiver tudo correto, é feita a gravação dos dados do formulário passando o parâmetro 1 (no qual a Stored Procedure foi declarada para inserção).
No botão Alterar é colocado o método btnAlterar_Click responsável por passar todos os valores do formulário através do parâmetro 2 e são feitas as alterações gravando no banco de dados.
No botão Excluir é colocado o método btnExcluir_Click responsável por executar a Stored Procedure para exclusão do cliente. Se o usuário desejar realmente o excluir, os campos dos formulários são limpos e os botões alterar e excluir desabilitados.
No botão Fechar é colocado o método btnFechar_Click responsável por sair da janela de cadastro.
Observação: Todos os métodos dos botões são declarados no evento Click localizados na aba Events em Properties.
Formulário para pesquisa de clientes
Agora vamos definir o que será exibido para o usuário para que ele faça as operações de pesquisa de clientes. No formulário frmPesquisaCliente.cs serão configuradas as Properties e também serão adicionados GroupBoxs, TextBox, RadioButtons, Buttons e DataGridView na tela, que ficarão de acordo com a Tabela 3.
Observação: o DataGridView se localiza em ToolBox na aba Data.
Tabela 3.Tela de Pesquisa de Clientes com seus componentes e suas respectivas configurações a serem colocadas no formulário.
Nome da propriedade do Form |
Como ficará definido |
|
Name |
frmPesquisaCliente |
|
Text |
Pesquisa de Clientes |
|
Nome do componente |
Nome da propriedade |
Como ficará definido |
GroupBox |
Name |
groupBox1 |
Text |
Critérios de busca |
|
GroupBox |
Name |
groupBox2 |
Text |
Informe o Nome ou o CPF do cliente |
|
RadioButton |
Name |
rdbCPF |
Text |
CPF |
|
RadioButton |
Name |
rdbNome |
Text |
Nome do cliente |
|
TextBox |
Name |
txtPesquisa |
DataGridView |
Name |
dgvClientes |
RowTemplate |
DataGridViewRow { Index=-1 } |
|
DefaultCellStyle |
DataGridViewCellStyle { } |
|
Button |
Name |
btnOK |
Text |
OK |
|
Button |
Name |
btnCancelar |
Text |
Cancelar |
Para ter uma ideia, o layout dos componentes na tela poderá ficar da forma como ilustra a Figura 11.
Figura 11. Arquivo frmPesquisaCliente.cs no modo Design ilustrando os componentes na tela.
Ao apertar a tecla F7 ou clicar com o botão direito sobre o formulário e ir em View Code, acrescente os códigos descritos na Listagem 8.
Listagem 8. Códigos a serem implementados no formulário de pesquisa de clientes.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CSharpComSQLServer
{
public partial class frmPesquisaCliente : Form
{
DadosDataSet.ClientesDataTable DTClientes = new DadosDataSet.ClientesDataTable();
DadosDataSetTableAdapters.ClientesTableAdapter TAClientes = new DadosDataSetTableAdapters.ClientesTableAdapter();
frmCliente frmCli;
public frmPesquisaCliente()
{
InitializeComponent();
}
public frmPesquisaCliente(frmCliente formularioClientes)
{
InitializeComponent();
frmCli = formularioClientes;
}
private void txtPesquisa_TextChanged(object sender, EventArgs e)
{
try
{
if (rdbCPF.Checked == true)
{
TAClientes.FillByBuscaCliCPF(DTClientes, txtPesquisa.Text);
dgvClientes.DataSource = DTClientes;
}
else if (rdbNome.Checked == true)
{
TAClientes.FillByBuscaCliNome(DTClientes, txtPesquisa.Text);
dgvClientes.DataSource = DTClientes;
}
}
catch (Exception ex)
{
MessageBox.Show("Falha ao localizar dados do cliente\n" + ex.Message, "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnOK_Click(object sender, EventArgs e)
{
try
{
DataGridViewRow linha;
linha = dgvClientes.CurrentRow;
frmCli.mskCPF.Text = linha.Cells["CPF"].Value.ToString();
frmCli.txtNome.Text = linha.Cells["Nome"].Value.ToString();
frmCli.txtEndereco.Text = linha.Cells["Endereco"].Value.ToString();
frmCli.mskTelefone.Text = linha.Cells["Telefone"].Value.ToString();
this.Close();
frmCli.btnAlterar.Enabled = true;
frmCli.btnExcluir.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show("Selecione um cliente\n" + ex.Message, "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnCancelar_Click(object sender, EventArgs e)
{
this.Close();
}
private void frmPesquisaCliente_Load(object sender, EventArgs e)
{
TAClientes.FillByDados(DTClientes);
dgvClientes.DataSource = DTClientes;
}
}
}
Veja que é criada uma instância com o nome de DTClientes do tipo DadosDataSet.ClientesDataTable,responsável por controlar as ações de busca em um DataTable da propriedade DadosDataSet. Em seguida é instanciado o TAClientes do tipo DadosDataSetTableAdapters.ClientesTableAdapter, responsável por controlar as alterações do DataSetTableAdapters dos Clientes criados no arquivo DadosDataSet.
É criada em seguida uma variável do tipo frmCliente e seu construtor para que esse formulário seja “filho” e que o resto da aplicação não possa ser manipulado quando esse estiver aberto.
Dentro do evento TextChanged do txtPesquisa é criada uma condição: se o rdbCPF for marcado e algo for digitado, havendo coincidência com algum CPF cadastrado, são retornadas para o DataGridView as informações do registro e, se o rdbNome for marcado e algo for digitado, havendo coincidência com algum Nome cadastrado, são retornadas para o DataGridView as informações do registro.
Se o botão btnOK for clicado, é executado o evento Clicke é retornado para todos os campos do formulário de cadastro de clientes os dados para serem visualizados ou manipulados se houver sucesso na busca e na seleção da linha do registro.
Se o botão btnCancelar for clicado, é executado o evento Click e a janela de pesquisa de clientes é fechada.
Quando o formulário é iniciado (evento Load), todos os clientes são buscados e exibidos para dentro do DataGridView.
Depois de feita toda essa implementação, basta salvar todos os arquivos em Save All (Ctrl + Shift + S) e apertar F5 (Start Debbuging) para executar o sistema.
Com isso, temos o nosso sistema de cadastro concluído. Espero que tenham gostado e até a próxima.