Os aplicativos multicamadas dividem a funcionalidade em várias camadas separadas por agrupamentos lógicos onde estão as suas funcionalidades. Esse artigo é o primeiro de uma série, as quais apresentam um exemplo prático e simples abordando o desenvolvimento em multicamadas em C#.

Este artigo atende a solicitação de vários leitores que pediram um exemplo do desenvolvimento em C# ao terem acompanhado a série anterior do desenvolvimento de uma aplicação para disk-pizza feita em VB.NET.

A Programação Orientada a Objetos (POO) possibilita uma abordagem simples para a utilização de dados usando objetos. Neste exemplo, as camadas estarão dispostas no mesmo computador, mas os conceitos e funcionalidades aqui descritos poderão ser utilizadas de forma igual em ambientes distribuídos.

Estrura em três camadas:

A Figura 1 - Camadas da Aplicação apresenta a estrutura básica de um aplicativo exemplo que será desenvolvido em C# com a base de dados em SQL Server.

Camadas da Aplicação
Figura 1 - Camadas da Aplicação

Camada de Dados

Também conhecida como camada de informações, responsável por maner os dados pertencentes ao aplicativo. Essa camada normalmente armazena dados em um sistema gerenciador de banco de dados relacional (SGBDR) (Deitel et al 2002). No exemplo que é apresentado será utilizado o SQL Server 2005, nada impede que o leitor utilize outro, desde que adapte as strings de conexão e declarações de objetos na linguagem. É recomendável porém, que seja utilizado o SQL Server 2005 ou o SQL Server 2005 Express Edition.

Camada Intermediária

A camada intermediária implementa a lógica de negócio e a lógica do controlador. Essa camada atua como intermediário entre os dados da camada de apresentação e os clientes do aplicativo. A lógica do controlador processa os pedidos do cliente e recupera do banco de dados. A lógica de negócios representam os métodos correspondentes as regras do negócio e garante que os dados sejam confiáveis, antes que o aplicativo servidor atualize o banco de dados ou apresente os dados aos usuários. Exemplos:

  • Antes de gravar os dados de um cliente no banco de dados, na camada lógica de negócios, poderia haver uma regrar para checar se a data de nascimento do cliente por exemplo não é maior que a data atual.
  • Se os campos obrigatórios foram preenchidos com dados válidos, etc...,

Ou seja, as regras de negócio dizem como os usuários/clientes podem e não podem acessar dados do aplicativo e como os aplicativos processam os dados. (Deitel et al, 2002).

Camada de Apresentação

Também conhecida como camada de interface com o usuário ou camada superior, que no caso do exemplo que será apresentado são os formulários tipo Windows, se fosse uma aplicação para Web seriam os navegadores. A camada de apresentação interage com a camada intermediária para fazer pedidos e recuperar dados da camada de dados. Então, a camada do cliente exibe para o usuário os dados recuperados pela camada intermediária.

Sistema de Controle de Apólices de Seguros de Veículos

Este visto no Diagrama de ER representa um modelo simplificado de um sistema de controle de apólices de seguro para veículos automotores.

Ao examinar a Figura 2 - Sistema Controle de Apólices de Seguro - Baseado em (Guedes, 2006) percebe-se:

  1. Que um cliente para ser cliente efetivamente precisa possuir no mínimo uma apólice, podendo ter mais carros segurados, no entanto uma apólice pertence de forma exclusiva a um cliente.
  2. Que uma apólice pode ser paga em várias parcelas. Que uma apólice refere-se a um veículo de um modelo determinado. E que esse mesmo modelo de veículo pode estar segurado em outra apólice de outro cliente.
  3. Que um sinistro pertece a uma única apólice. Mas esta apólice pode ter uma ou mais sinistros ocorridos. Que o sinistro cadastrado pode ser de um tipo ou mais e representar vários danos.

Nota: Para fins didáticos este modelo está simplificado, faltam campos, poderíamos aplicar mais regras de normalização, como por exemplo a marca do veículo poderia estar em uma tabela separada e assim por diante. Porém isso foge ao escopo do objetivo principal que é o aprendizado do desenvolvimento em camadas.

Diagrama de Entidade Relacionamento

A Figura 2 - Sistema Controle de Apólices de Seguro - Baseado em (Guedes, 2006) representa o Digrama de ER explicado anteriormente.

Sistema Controle de Apólices de Seguro - Baseado em (Guedes, 2006)
Figura 2 -Sistema Controle de Apólices de Seguro - Baseado em (Guedes, 2006)

Preparar a camada de dados, a qual será acessada pelos métodos da classe intermediária que representam a lógica do controlador, no caso do exemplo apresentado.

Mão na Massa

Inicie o Sql Server 2005 crie um banco de dados chamado seguros, Abra uma janela New Query e execute o script abaixo para a criação das tabelas já com os relacionamentos, se assim o desejar. Caso contrário, se desejar criar manualmente consulte o artigo anterior que escrevi sobre a camada de dados.

Nota: Não esqueça de criar o banco com o nome seguros, para facilitar o desenvolvimento do aplicativo.
USE SEGUROS
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 IF NOT EXISTS (SELECT * FROM sys.objects 
  WHERE object_id = OBJECT_ID(N'[dbo].[tbCliente]') AND type in (N'U'))
 BEGIN
 CREATE TABLE [dbo].[tbCliente](
 [idCli] [int] NOT NULL,
 [nomeCli] [nvarchar](50) NOT NULL,
 [enderecoCli] [nvarchar](50) NULL,
 [foneCli] [nvarchar](20) NULL,
 [faxCli] [nvarchar](20) NULL,
 [obsCli] [nvarchar](max) NULL,
 CONSTRAINT [PK_tbCliente] PRIMARY KEY CLUSTERED 
 (
 [idCli] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 END
 GO
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 IF NOT EXISTS (SELECT * FROM sys.objects 
  WHERE object_id = OBJECT_ID(N'[dbo].[tbDano]') AND type in (N'U'))
 BEGIN
 CREATE TABLE [dbo].[tbDano](
 [idDano] [int] NOT NULL,
 [descDano] [nvarchar](50) NULL,
 CONSTRAINT [PK_tbDano] PRIMARY KEY CLUSTERED 
 (
 [idDano] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 END
 GO
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 IF NOT EXISTS (SELECT * FROM sys.objects 
  WHERE object_id = OBJECT_ID(N'[dbo].[tbTipo]') AND type in (N'U'))
 BEGIN
 CREATE TABLE [dbo].[tbTipo](
 [idTipo] [int] NOT NULL,
 [descTipo] [nvarchar](30) NULL,
 CONSTRAINT [PK_tbTipo] PRIMARY KEY CLUSTERED 
 (
 [idTipo] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 END
 GO
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 IF NOT EXISTS (SELECT * FROM sys.objects 
  WHERE object_id = OBJECT_ID(N'[dbo].[tbModelo]') AND type in (N'U'))
 BEGIN
 CREATE TABLE [dbo].[tbModelo](
 [idModelo] [int] NOT NULL,
 [descModelo] [nvarchar](50) NOT NULL,
 [descMarca] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_tbModelo] PRIMARY KEY CLUSTERED 
 (
 [idModelo] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 END
 GO
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 IF NOT EXISTS (SELECT * FROM sys.objects 
  WHERE object_id = OBJECT_ID(N'[dbo].[tbApolice]') AND type in (N'U'))
 BEGIN
 CREATE TABLE [dbo].[tbApolice](
 [idApolice] [nvarchar](8) NOT NULL,
 [idCli] [int] NOT NULL,
 [kmVeiApolice] [int] NOT NULL,
 [numApolice] [int] NOT NULL,
 [dataApolice] [datetime] NULL,
 [dataValApolice] [datetime] NULL,
 [valorApolice] [float] NULL,
 [idModelo] [int] NULL,
 [sinistroApolice] [bit] NULL,
 [idSinistro] [int] NULL,
 CONSTRAINT [PK_tbVeiculoSegurado] PRIMARY KEY CLUSTERED 
 (
 [idApolice] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 END
 GO
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 IF NOT EXISTS (SELECT * FROM sys.objects 
  WHERE object_id = OBJECT_ID(N'[dbo].[tbParcela]') AND type in (N'U'))
 BEGIN
 CREATE TABLE [dbo].[tbParcela](
 [nroParc] [int] NOT NULL,
 [idApolice] [nvarchar](8) NOT NULL,
 [dataVenParcela] [datetime] NOT NULL,
 [valParcela] [float] NOT NULL,
 [quitadaParcela] [bit] NULL,
 [quitadaData] [datetime] NULL,
 CONSTRAINT [PK_tbParcela] PRIMARY KEY CLUSTERED 
 (
 [nroParc] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 END
 GO
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 IF NOT EXISTS (SELECT * FROM sys.objects 
  WHERE object_id = OBJECT_ID(N'[dbo].[tbSinistro]') AND type in (N'U'))
 BEGIN
 CREATE TABLE [dbo].[tbSinistro](
 [idSinistro] [int] NOT NULL,
 [dataSinistro] [datetime] NOT NULL,
 [descSinistro] [nvarchar](50) NOT NULL,
 [idTipo] [int] NOT NULL,
 [idDano] [int] NOT NULL,
 CONSTRAINT [PK_tbSinistro] PRIMARY KEY CLUSTERED 
 (
 [idSinistro] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 END
 GO
 IF NOT EXISTS (SELECT * FROM sys.foreign_keys 
  WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbApolice_tbCliente]') 
  AND parent_object_id = OBJECT_ID(N'[dbo].[tbApolice]'))
 ALTER TABLE [dbo].[tbApolice] WITH CHECK ADD 
  CONSTRAINT [FK_tbApolice_tbCliente] FOREIGN KEY([idCli])
 REFERENCES [dbo].[tbCliente] ([idCli])
 GO
 ALTER TABLE [dbo].[tbApolice] CHECK CONSTRAINT [FK_tbApolice_tbCliente]
 GO
 IF NOT EXISTS (SELECT * FROM sys.foreign_keys 
  WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbApolice_tbModelo]') 
  AND parent_object_id = OBJECT_ID(N'[dbo].[tbApolice]'))
 ALTER TABLE [dbo].[tbApolice] WITH CHECK 
  ADD CONSTRAINT [FK_tbApolice_tbModelo] FOREIGN KEY([idModelo])
 REFERENCES [dbo].[tbModelo] ([idModelo])
 GO
 ALTER TABLE [dbo].[tbApolice] CHECK CONSTRAINT [FK_tbApolice_tbModelo]
 GO
 IF NOT EXISTS (SELECT * FROM sys.foreign_keys 
  WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbApolice_tbSinistro]') 
  AND parent_object_id = OBJECT_ID(N'[dbo].[tbApolice]'))
 ALTER TABLE [dbo].[tbApolice] WITH NOCHECK ADD 
  CONSTRAINT [FK_tbApolice_tbSinistro] FOREIGN KEY([idSinistro])
 REFERENCES [dbo].[tbSinistro] ([idSinistro])
 GO
 ALTER TABLE [dbo].[tbApolice] NOCHECK CONSTRAINT [FK_tbApolice_tbSinistro]
 GO
 IF NOT EXISTS (SELECT * FROM sys.foreign_keys 
  WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbParcela_tbApolice]') 
  AND parent_object_id = OBJECT_ID(N'[dbo].[tbParcela]'))
 ALTER TABLE [dbo].[tbParcela] WITH CHECK ADD 
  CONSTRAINT [FK_tbParcela_tbApolice] FOREIGN KEY([idApolice])
 REFERENCES [dbo].[tbApolice] ([idApolice])
 GO
 ALTER TABLE [dbo].[tbParcela] CHECK CONSTRAINT [FK_tbParcela_tbApolice]
 GO
 IF NOT EXISTS (SELECT * FROM sys.foreign_keys 
  WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbSinistro_tbDano]') 
  AND parent_object_id = OBJECT_ID(N'[dbo].[tbSinistro]'))
 ALTER TABLE [dbo].[tbSinistro] WITH CHECK ADD 
  CONSTRAINT [FK_tbSinistro_tbDano] FOREIGN KEY([idDano])
 REFERENCES [dbo].[tbDano] ([idDano])
 GO
 ALTER TABLE [dbo].[tbSinistro] CHECK CONSTRAINT [FK_tbSinistro_tbDano]
 GO
 IF NOT EXISTS (SELECT * FROM sys.foreign_keys 
  WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbSinistro_tbTipo]') 
  AND parent_object_id = OBJECT_ID(N'[dbo].[tbSinistro]'))
 ALTER TABLE [dbo].[tbSinistro] WITH CHECK ADD 
  CONSTRAINT [FK_tbSinistro_tbTipo] FOREIGN KEY([idTipo])
 REFERENCES [dbo].[tbTipo] ([idTipo])
 GO
 ALTER TABLE [dbo].[tbSinistro] CHECK CONSTRAINT [FK_tbSinistro_tbTipo]

Se tiver dúvidas em como executar esse script, siga os procedimentos abaixo indicados:

  1. Na janela do Microsoft SQL Server Management Studio (Figura 3), clique com o botão direito do mouse sobre Databases, escolha New Database...
    New Database...
    Figura 3 - New Database...
  2. Na janela New Database, digite o nome do banco de dados, seguros e em seguida clique em OK, como mostra a Figura 4.
    New Database: seguros
    Figura 4 - New Database: seguros
  3. Na janela do Object Explorer apresentada na Figura 5, clique com o botão direito do mouse sobre o banco de dados criado (seguros) e escolha new query.
    Object Explorer - New Query
    Figura 5 - Object Explorer - New Query
  4. Na janela query da Figura 6, copie script desse artigo e cole nessa janela. Em seguida clique no botão execute.
    Janela Query e Botão Execute
    Figura 6 - Janela Query e Botão Execute
  5. Expanda no Object Explorer [+] para ver o banco de dados seguro e clique sobre Database Diagram com o botão direito. Responda afirmativamente a caixa de diálogo para criar um novo diagrama, como mostra a Figura 7.
    Novo Diagrama do Banco de Dados
    Figura 7 - Novo Diagrama do Banco de Dados
  6. Adicione todas as tabelas, para que fique parecido com a Figura 7 - Sistema Controle de Apólices de Seguro - Baseado em (Guedes, 2006).

Lógica do Controlador

Sabemos que a programação orientada a objetos (POO) possibilita uma abordagem simples para a utilização de dados usando objetos. Até agora foi apresentado um cenário para o desenvolvimento da aplicação e criado o Banco de Dados com as respectivas tabelas e o mapeamento Entidade Relacionamento entre elas.

Agora será apresentada a classes da camada “2 – Camada Intermediaria” que representa a lógica do controlador, classe essa que faz a interface entre a lógica de negócio e os dados no banco de dados, como mostra a Figura 8.

Observe Camada 2.1
Figura 8 - Observe Camada 2.1

Os métodos da lógica do controlador devem assegurar a confiabilidade dos dados antes que o servidor de Banco de Dados atualize ou exiba as informações ao cliente do aplicativo (camada de apresentação).

Sabe-se que de acordo com as necessidades atuais das empresas e alterações constantes na legislação e evidentemente nos aplicativos, o modelo de desenvolvimento em várias camadas, com a utilização de classes com finalidades específicas, facilitam a atualização das aplicações e também permitem o reuso do código.

Camada Intermediaria

Vamos começar organizando o projeto proposto. Para isso abra inicie um novo projeto em Visual C# - Windows Application. Dê o nome para esse projeto de Seguros_OO e clique em OK, como mostra a Figura 9.

New Project
Figura 9 - New Project

Para que possa ser organizado e visualizado o código nas diferentes camadas, adicione a este projeto duas novas pastas chamadas: “Camada Intermediaria” e “Camada Apresentacao”. Expanda a pasta “Camada Intermediaria” e crie duas novas pastas chamadas respectivamente Logica Controlador e Logica Negocios.

Para criar, clique com o botão direito do mouse sobre a solução, selecione Add New Folder. Dê os nomes conforme acima, ao final você terá o resultado da Figura 10:

Pastas
Figura 10 - Pastas

Vamos adicionar a primeira classe, que será responsável pelo controle dos dados. Essa classe fará parte da Lógica do Controlador. Chamaremos essa classe de “clsDados.vb”.

Clique com o botão direito sobre “Logica Controlador” e selecione Add .. Class .. Dê o nome de “clsDados.cs” para essa classe, conforme Figura 11.

Classe clsDados.cs
Figura 11 - Classe clsDados.cs

Vamos ao código da Classe de Dados, “clsDados.cs”. Classe genérica que é utilizada para fazer a interface entre as classes contidas na lógica de negócios e a camada de dados. Nela pode-se realizar as operações básicas de banco de dados, como: inclusão, alteração, consulta e exclusão.

Revisando: A orientação a objetos usa classes para encapsular variáveis de instância (dados) e métodos (comportamentos).

Estrutura da classe: clsDados

Estrutura da classe: clsDados

Digitar o código abaixo na classe “clsDados.cs”.Dê um duplo clique sobre o nome do arquivo e digite. Se preferir, é claro, copie.

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
 
namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
    class clsDados
    {
        // Adapte a string de acordo com sua conexão.
        string conexao = "Data Source=(local);Initial Catalog=seguros;Integrated Security=True";
       
        //Classe para Abrir o Banco de Dados
        private SqlConnection AbrirBanco()
        {
            SqlConnection cn = new SqlConnection(conexao);
            cn.Open();
            return cn;
        }
 
        //Classe para Fechar o Banco de Dados
        public void FecharBanco(SqlConnection cn)
        {
            if (cn.State==ConnectionState.Open)
                cn.Close();
        }
        //Classe para execução de comando
        public void ExecutarComando(string strQuery)
        {
            SqlConnection cn = new SqlConnection();
            try
            {
                cn = AbrirBanco();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = strQuery.ToString();
                cmd.CommandType = CommandType.Text;
                cmd.Connection = cn;
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharBanco(cn);
            }
        }
        //Classe que retorna um objeto DataSet
        public DataSet RetornarDataSet(string strQuery)
        {
            SqlConnection cn = new SqlConnection();
            try
            {
                cn = AbrirBanco();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = strQuery.ToString();
                cmd.CommandType = CommandType.Text;
                cmd.Connection = cn;
                cmd.ExecuteNonQuery();
                /*  Declarado um dataadapter e um dataset
                    passar o comando para o da (SqlDataAdapter) e
                    carregar o dataset com resultado da busca */
                SqlDataAdapter da = new SqlDataAdapter();
                DataSet ds = new DataSet();
                da.SelectCommand= cmd;
                da.Fill(ds);
                return ds;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharBanco(cn);
            }
        }
        //Classe para retornar um DataReader()
        public SqlDataReader  RetornarDataReader(string strQuery)
        {
            SqlConnection cn = new SqlConnection();
            try
            {
                cn = AbrirBanco();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = strQuery.ToString();
                cmd.CommandType = CommandType.Text;
                cmd.Connection = cn;
                return cmd.ExecuteReader();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharBanco(cn);
            }
        }
 
        //Classe para retornar um Id Numérico
        public int RetornarIdNumerico(string strQuery)
        {
            SqlConnection cn = new SqlConnection();
            try
            {
                cn = AbrirBanco();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = strQuery.ToString();
                cmd.CommandType = CommandType.Text;
                cmd.Connection = cn;
                SqlDataReader dr = cmd.ExecuteReader();
                int codigo;
                if (dr.Read())
                    codigo = Convert.ToInt16(dr[0]) + 1;
                else
                    codigo = 1;
                return codigo;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharBanco(cn);
            }
        }
    }
}

Lógica de Negócios

Nesse momento serão apresentadas as classes que compõe a regra de negócios do Sistema de Controle de Apólices de Seguro. A lógica de negócios na camada 2 apresentada impõe as regras de negócio e garantem a confiabilidade dos dados, antes que o aplicativo servidor atualize o banco de dados ou apresente os dados para os usuários (negociação feita nessa camadas, pela classe que representa a lógica do controlador). As regras de negócio dizem como os clientes podem e não podem acessar os dados do aplicativo e como os aplicativos processam esses dados, como mostra a Figura 12.

Lógica de Negócios
Figura 12 - Lógica de Negócios

Camada Intermediaria: Lógica de Negócios

A primeira classe que será apresentada é a classe clnClientes.cs, nesta classe serão definidos os campos membros, atributos/propriedades e métodos.

Como boa prática de programação as variáveis de instância da classe estarão definida como PRIVATE, sendo acessíveis apenas dentro da própria classe pelas propriedades que utilizaremos através de seus métodos de acesso para exibir ou ler os dados. (Métodos Get e Set).

Com o aplicativo aberto Seguros_OO, dê um clique com o botão direito do mouse sobre a pasta [Logica Negocios], selecione a opção ADD à New Item e Adicione uma nova classe, com o nome “clnClientes.cs”, como mostra a Figura 13.

Classe Clientes
Figura 13 – Classe Clientes

Nota do Autor: Procurei comentar ao máximo esta classe, para que facilite o entendimento, no entanto, caso algo não fique claro, podem-me escrever, sempre coloco o meu e-mail no final dos artigos. Nessa camada você poderia implementar algumas regras que ao longo do artigo não vou definir, pois o objetivo aqui é não complicar o entendimento. Contudo, fique a vontade para incluir regras nessa camada, tais como checagem dos dados, consistência de valores.

Antes de digitar o código, a classe clnClientes.cs na Figura 14 mostra como ela está definida:

Detalhes da Classe clnClientes.cs
Figura 14 - Detalhes da Classe clnClientes.cs

Pronto agora é só digitar, ou copiar, se assim o preferir:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
 
namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
    public class clnClientes
    {
        //1 - Campos privados a classe
        private int idCli;
        private string nomeCli;
        private string enderecoCli;
        private string foneCli;
        private string faxCli;
        private string obsCli;
 
        //2 - propriedades, acesso aos campos privados
        public int IdCli
        {
            get { return idCli; }
            set { idCli = value; }
        }
        public string NomeCli
        {
            get { return nomeCli; }
            set { nomeCli = value; }
        }
        public string EnderecoCli
        {
            get { return enderecoCli; }
            set { enderecoCli = value; }
        }
        public string FoneCli
        {
            get { return foneCli; }
            set { foneCli = value; }
        }
        public string FaxCli
        {
            get { return faxCli; }
            set { faxCli = value; }
        }
        public string ObsCli
        {
            get { return obsCli; }
            set { obsCli = value; }
        }
 
        //3 - métodos da classe de Negócios (clnCliente.cs)
       
        //3.1 Buscar dados do cliente cujo codigo foi especificado
        public void Buscar()
        {
            string csql;
            csql = "Select * From tbCliente where idCli=" + IdCli;
            DataSet ds;
            clsDados seguros = new clsDados();
            ds = seguros.RetornarDataSet(csql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                Array dados = ds.Tables[0].Rows[0].ItemArray;
                idCli = Convert.ToInt16(dados.GetValue(0));
                nomeCli = Convert.ToString(dados.GetValue(1));
                enderecoCli = Convert.ToString(dados.GetValue(2));
                foneCli = Convert.ToString(dados.GetValue(3));
                faxCli = Convert.ToString(dados.GetValue(4));
                obsCli = Convert.ToString(dados.GetValue(5));
            }
        }
       
        //3.2 Buscar o próximo Id Numerico para
        //inclusao de um novo cliente.
        public int BuscarId()
        {
            string csql;
            csql = "Select Top 1 (IdCli) From TbCliente order by IdCli desc";
            int IdBuscado;
            clsDados seguros = new clsDados();
            IdBuscado=seguros.RetornarIdNumerico(csql);
            return IdBuscado;
        }
 
        //3.3 Método para incluir um novo cliente no
        //Banco de dados
        public void Gravar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Insert into tbCliente");
            csql.Append("(");
            csql.Append("idCli,");
            csql.Append("nomeCli,");
            csql.Append("enderecoCli,");
            csql.Append("foneCli,");
            csql.Append("faxCli,");
            csql.Append("obsCli) Values(");
            csql.Append(idCli);
            csql.Append(",'" + nomeCli +"',");
            csql.Append("'" + enderecoCli + "',");
            csql.Append("'" + foneCli  + "',");
            csql.Append("'" + faxCli + "',");
            csql.Append("'" + obsCli + "')");
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
 
        //3.4 Método para atualizar (alterar um registro)
        public void Atualizar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Update tbCliente ");
            csql.Append("set idCli=");
            csql.Append(IdCli);
            csql.Append(", nomeCli='");
            csql.Append(nomeCli);
            csql.Append("', enderecoCli='");
            csql.Append(enderecoCli);
            csql.Append("', foneCli='");
            csql.Append(foneCli);
            csql.Append("', faxCli='");
            csql.Append(faxCli);
            csql.Append("', obsCli='");
            csql.Append(obsCli);
            csql.Append("' where idCli=");
            csql.Append(IdCli);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
      
        //3.5 Método para excluir um cliente do
        //Banco de dados
        public void Excluir()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Delete From tbCliente ");
            csql.Append(" where idCli=");
            csql.Append(IdCli);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
    }
}

Até o momento foi apresentada a primeira classe que compõe a regras de negócios do Sistema de Controle de Apólices de Seguro proposto. Como já apresentado a lógica de negócios na camada 2 impõe as regras de negócio e garantem a confiabilidade dos dados, antes que o aplicativo servidor atualize o banco de dados ou apresente os dados para os usuários (acesso aos dados: tarefa da classe clnDados.cs – lógica do controlador).

Fica como desafio ao leitor, criar as demais classes básicas que compões a lógica de negócios.

A seguir será apresentada a camada de apresentação, onde serão criados o formulário para cadastro de dados do cliente e o formulário de pesquisa genérico que poderá ser utilizado em toda a aplicação.

Nota: Neste exemplo não separamos as camadas em projetos diferentes dentro de uma solução. Usamos apenas pastas (folders) para isso. Nada impede que você adote essa prática, projetos maiores ficam de forma melhor organizados com esse procedimento. A única coisa é que não pode-se esquecer de colocar as referências aos projetos em uso. Ex: o projeto que conteriam as regras de negócio teriam que ter uma referencia adicionada ao projeto do controlador, e assim por diante.

É importante destacar que as camadas nos dizem como agrupar os componentes já o modelo MVC apresenta a forma de interação entre essas. O nome dado a segunda camada (Intermediária) acredito que esteja bem adequado, no entanto a lógica do controlador, deve ser vista como a parte da camada que contém as classes com o conhecimento necessário sobre como persistir objetos no banco de dados, como usei o referencial teórico apresentado no final do artigo (Deitel et al, 2002), esta persistência encontra-se apresentada como “lógica do controlador”, tradução técnica feita também na versão brasileira do Livro “Como programar C#”. É importante que o leitor não confunda estes conceitos. Aqui na DevMedia, os amigos podem encontrar artigos interessantes demonstrando na prática os conceitos de MVC que em projetos maiores é uma boa prática a realização do mapeamento entre os objetos de domínio com o banco de dados. O leitor pode conhecer mais sobre esse mapeamento utilizando por exemplo o NHibernate, aqui no portal com as vídeo aulas do Rodrigo.

Camada de Apresentação

Será apresentada a camada de apresentação, onde criaremos um formulário para cadastro de dados dos clientes e um formulário de pesquisa genérico que poderá ser reutilizado em toda a aplicação, como mostra a Figura 15.

Camadas da Aplicação
Figura 15 - Camadas da Aplicação

A camada de aprestação ou camada do cliente ou ainda camada superior é a interface com o usuário, que neste caso são as janelas Winforms do nosso aplicativo exemplo. A camada do cliente interage com a camada intermediária para fazer pedidos e recuperar dados da camada de dados. Então, a camada de apresentação exibe para o usuário os dados recuperados pela camada intermediária. Esta divisão em camadas certamente deixa o código com uma leitura e controle mais fácil. Pois as regras estão em uma camada isolada. Supondo que nossa aplicação fosse cliente de uma aplicação Web Service em um servidor numa intranet, as regras poderiam estar nas classes desse único servidor facilitando assim a manutenção, pois caso o código venha a ser alterado, não é necessário compilar as alterações nas máquinas clientes. Um bom trabalho poupado.

Criaremos nesse momento o primeiro formulário, que servirá de interface com os dados do cliente. Onde o usuário poderá, incluir, alterar, excluir e pesquisar por um determinado cliente. Nota, lembre-se que a idéia é criar um formulário para pesquisa genérico que venha a servir em outros tipos de pesquisa, como por exemplo: apólices de seguro ou parcelas do cliente.

Mão na Massa:

Com o aplicativo aberto Seguros_OO, você deve ter um formulário Form1 (Figura 16) na janela do solution explorer, arraste-o para dentro da Camada de Apresentação, pasta [Camada Apresentacao].

Form1.cs
Figura 16 – Form1.cs

Caso você não tenha esse formulário, clique com o botão direito do mouse sobre a camada de apresentação e adicione um novo formulário.

Renomeie esse formulário para FrmClientes.cs, como mostra a Figura 17.

Formulário renomeado
Figura 17 - Formulário renomeado

Crie uma interface arrastando os objetos para a tela conforme abaixo e definindo o nome dos controles como apresentado em azul na Figura 18:

Cadastro de Clientes
Figura 18 - Cadastro de Clientes

Altere as propriedades de todos os botões exceto (btnProcurar e btnSair), como abaixo:

Controle Propriedade Valor
btnIncluir Enabled false
btnAtualizar Enabled false
btnExcluir Enabled false
btnCancelar Enabled false

O formulário deve funcionar desta forma:

  • Quando for carregado o foco deve estar no primeiro campo o controle txtidCli
  • Quando o usuário sair desse controle, faremos uma busca no Banco de Dados para retornar o código digitado, caso não tenha o código será habilitado a opção de incluir e caso contrário será habilitado o botão atualizar.

Selecione o controle txtidCli e na janela de eventos, veja Figura 19 - Janela para seleciona evento, e escolha o evento leave (para conhecedores do VB – lostfocus), dê um duplo clique nele e adicione o código abaixo:

Janela para selecionar evento
Figura 19 - Janela para selecionar evento

Código do evento Leave:

private void txtIdCli_Leave(object sender, EventArgs e)
          {
             int vidCli=0;
             if (txtIdCli.Text.Trim() != "")
             {
                  vidCli = int.Parse(txtIdCli.Text);
             }
              clnClientes cliente = new clnClientes();
              cliente.IdCli = vidCli;
              cliente.Buscar();
              if (cliente.NomeCli == null)
              {
                  //preparando para inclusao
                  LimparTxt(groupBox1);
                  txtIdCli.Text = "";
                  txtIdCli.Enabled = false;
                  btnIncluir.Enabled = true;
                  btnCancelar.Enabled = true;
              }
              else
              {
                  //preparando para alteracao
                  LimparTxt(groupBox1);
                  txtIdCli.Enabled = false;
                  txtIdCli.Text = Convert.ToString(cliente.IdCli);
                  txtnomeCli.Text = Convert.ToString(cliente.NomeCli);
                  txtenderecoCli.Text = Convert.ToString(cliente.EnderecoCli);
                  txtfoneCli.Text = Convert.ToString(cliente.FoneCli);
                  txtfaxCli.Text = Convert.ToString(cliente.FaxCli);
                  txtobsCli.Text = Convert.ToString(cliente.ObsCli);
                  btnAtualizar.Enabled = true;
                  btnCancelar.Enabled = true;
                  btnExcluir.Enabled = true;
   
              }
          }

É necessário que você indique o local de armazenamento das classes nas declarações de using. Neste caso indique:

...
  using System.Text;
  using System.Windows.Forms;
  using Seguros_OO.Camada_Intermediaria.Logica_Negocios;

No código anterior observe as linhas destacadas em negrito e itálico nos blocos if e else. Invoca-se um método chamado LimparTxt passando como parâmetro o objeto do tipo GroupBox chamado groupBox1. A idéia é que quando o código for invocado ele “limpe” todas as caixas de textos que estão dentro do groupBox.

Acrescente o código a seguir, logo acima ou abaixo do método anterior.


 //Método público para limpar caixas de texto
          public void LimparTxt(Control controles)
          {
              foreach (Control ctl in controles.Controls)
              {
                  if (ctl is TextBox) ctl.Text = "";
              }
          }

Na lista abaixo código encontra-se o código do botão incluir. Observe como este código é limpo. Lembre-se que as regras para gravação do cliente poderiam ter sido criadas na classe clnCliente no método Gravar ou nos métodos de escrita Set daquela classe.

 private void btnIncluir_Click(object sender, EventArgs e)
          {
              try
              {
                  clnClientes cliente = new clnClientes();
                  //Dispara o método para buscar o IdCli
                  cliente.IdCli = cliente.BuscarId();
                  cliente.NomeCli = txtnomeCli.Text;
                  cliente.EnderecoCli = txtenderecoCli.Text;
                  cliente.FoneCli = txtfoneCli.Text;
                  cliente.FaxCli = txtfaxCli.Text;
                  cliente.ObsCli = txtobsCli.Text;
                  cliente.Gravar();
                  string mensagem = "Registro Cliente: " +
                      cliente.IdCli + "\nNome: " + cliente.NomeCli +
                      "\nGravado com sucesso";
                  MessageBox.Show(mensagem, "Sucesso", 
                      MessageBoxButtons.OK,
                      MessageBoxIcon.Information);
                  LimparTxt(groupBox1);
                  btnIncluir.Enabled = false;
                  btnCancelar.Enabled = false;
                  txtIdCli.Enabled = true;
                  txtIdCli.Focus();
              }
              catch (Exception ex)
              {
                  MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
              }
          }

Abaixo o código do botão atualizar.

private void btnAtualizar_Click(object sender, EventArgs e)
          {
              try
              {
                  clnClientes cliente = new clnClientes();
                  cliente.IdCli = int.Parse(txtIdCli.Text);
                  cliente.NomeCli = txtnomeCli.Text;
                  cliente.EnderecoCli = txtenderecoCli.Text;
                  cliente.FoneCli = txtfoneCli.Text;
                  cliente.FaxCli = txtfaxCli.Text;
                  cliente.ObsCli = txtobsCli.Text;
                  cliente.Atualizar();
                  string mensagem = "Registro Cliente: " +
                      cliente.IdCli + "\nNome: " + cliente.NomeCli +
                      "\nAlterado com sucesso";
                  MessageBox.Show(mensagem, "Sucesso",
                      MessageBoxButtons.OK,
                      MessageBoxIcon.Information);
                  LimparTxt(groupBox1);
                  btnAtualizar.Enabled = false;
                  btnCancelar.Enabled = false;
                  btnExcluir.Enabled = false;
                  txtIdCli.Enabled = true;
                  txtIdCli.Focus();
              }
              catch (Exception ex)
              {
                  MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
              }

Abaixo o código do botão Excluir.

private void btnExcluir_Click(object sender, EventArgs e)
          {
              string pergunta;
              pergunta = "Deseja excluir o cliente: \n" +
                  txtIdCli.Text + ": " + txtnomeCli.Text +
                  "  ?";
              int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Atenção", 
                  MessageBoxButtons.YesNo, 
                  MessageBoxIcon.Question));
              if (ret == 6)
              {
                  clnClientes cliente = new clnClientes();
                  cliente.IdCli = int.Parse(txtIdCli.Text);
                  cliente.NomeCli = txtnomeCli.Text;
                  cliente.Excluir();
                  string mensagem = "Registro Cliente: " +
                      cliente.IdCli + "\nNome: " + cliente.NomeCli +
                      "\nExcluído com sucesso";
                  MessageBox.Show(mensagem, "Sucesso",
                      MessageBoxButtons.OK,
                      MessageBoxIcon.Information);
                  LimparTxt(groupBox1);
                  btnAtualizar.Enabled = false;
                  btnCancelar.Enabled = false;
                  btnExcluir.Enabled = false;
                  txtIdCli.Enabled = true;
                  txtIdCli.Focus();
              }
              else
              {
                  MessageBox.Show("Operação Cancelada",
                      "Cancelada", MessageBoxButtons.OK,
                      MessageBoxIcon.Information);
              }
          }

Abaixo o código do botão cancelar.

 private void btnCancelar_Click(object sender, EventArgs e)
          {
              LimparTxt(groupBox1);
              btnIncluir.Enabled = false;
              btnAtualizar.Enabled = false;
              btnCancelar.Enabled = false;
              btnExcluir.Enabled = false;
              txtIdCli.Enabled = true;
              txtIdCli.Focus();
          }

Neste momento não será colocado código para o botão procurar. Retornaremos a este ponto em breve.

Abaixo código do último botão, o botão sair. A finalidade é apenas sair do formulário atual e não da aplicação, uma vez que esse não será o formulário principal deste nosso sistema exemplo.

private void btnSair_Click(object sender, EventArgs e)
          {
              this.Close();
          }

Bom, agora que já está pronto o formulário: cadastro de clientes, o próximo passo é criar um formulário genérico de consulta. Este formulário servirá para pesquisa em todas as tabelas do banco.

Agora, adicione um novo formulário (Figura 20) a essa aplicação e renomei-o com o nome FrmPesquisa.cs, coloque (ou crie) esse formulário dentro da pasta [Camada Apresentacao].

Solution Explorer
(FrmPesquisa.cs)
Figura 20 - Solution Explorer (FrmPesquisa.cs)

Quem acompanhou a série de artigos do desenvolvimento em camada para o Visual Basic, deve se lembrar deste formulário. A ideia aqui é a mesma, só que em C#, mas vale a pena relembrar.

13) Arraste para o formulário FrmConsulta os seguintes objetos 02 groupboxs, 03 labels, 02 combobox, 01 textbox, 01 button e 01 datagrid, conforme Figura 21:

Formulário FrmPesquisa.cs
Figura 21 - Formulário FrmPesquisa.cs

14) Altere as propriedades dos objetos do formulário conforme quadro:

Objeto Propriedade Valor
ComboBox1 NAME DROPDOWNSTYLE cmbCampo DropDownList
ComboBox2 NAME DROPDOWNSTYLE cmbParam DropDownList
TextBox1 NAME TxtBusca
Button1 NAME btnFiltrar
DataGridView1 NAME Dgv1
Os controles do tipo GroupBox não precisam alterar a propriedade NAME.

15) Agora vamos retornar ao formulário FrmClientes, para adicionar o código que responde ao evento click no botão procurar. No entanto declare a biblioteca com o keyword using antes.

...
  using System.Windows.Forms;
  using Seguros_OO.Camada_Intermediaria.Logica_Negocios;
  using Seguros_OO.Camada_Apresentacao;

16) Agora sim. Vamos ao código do botão procurar:

 private void btnProcurar_Click(object sender, EventArgs e)
          {
              FrmPesquisa f = new FrmPesquisa();
              f.Text = "Consulta dados dos clientes";
              f.Tag = "tbCliente"; //nome da tabela (macete)  :)
              f.ShowDialog();
          }

17) Alterne agora para o formulário FrmPesquisa e declare as bibliotecas necessárias para instanciamento das classes (namespace).

using Seguros_OO.Camada_Intermediaria.Logica_Negocios;

18) Neste momento adicione o código para o evento Load do formulário “FrmPesquisa”.

private void FrmPesquisa_Load(object   sender, EventArgs e)
           {
               string csql = "Select   * From " + this.Tag.ToString();
               clsDados geral = new clsDados();
               DataSet   ds = geral.RetornarDataSet(csql);
               dgv1.DataSource = ds.Tables[0];
               ds.Tables[0].Columns[0].ColumnName.ToString();
               cmbCampo.Items.Clear();
               for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
   cmbCampo.Items.Add(ds.Tables[0].Columns[i].ColumnName.ToString());
           }

O método acima é disparado quando o formulário é carregado, Inicialmente declaramos uma string chamada csql com a cláusula select, cujo objetivo é buscar no banco de dados todos os campos da tabela indicada na propriedade Tag do formulário corrente. Veja que essa propriedade foi carregada com o nome da tabela indica no item 16, destacado como “macete”. Desta forma este formulário pode ser reaproveitado em qualquer chamada a partir de outros formulário, desde que você indique na hora do instancimento do formulário o nome da tabela desejada. Uma boa idéia é para você é melhorar mais tarde o funcionamento deste formulário.

Ainda nesse código através de uma estrutura de repetição for, percorremos todas as colunas (campos) da tabela em questão e adicionamos o seu nome (nome do campo) ao controle cmbCampo.

Agora vamos adicionar um código, para que quando o usuário escolha um campo no controle cmbCampo, seja preechido o cmbParam com os tipos de busca possível para o tipo de campo selecionado, ou seja, se o usuário escolher um campo tipo “string” o campo cmbParam deve ter as opções tipo: “começando com”, “terminando em”, “igual a”, “tem a palavra”, e se for int deve der opções do tipo: “>”, “<”, etc.

19) Código do cmbCampo (quando o usuário escolher um campo);

 private void cmbCampo_SelectedIndexChanged(object sender, EventArgs e)
          {
              int indiceCampo = cmbCampo.SelectedIndex;
              string tipocampo = this.dgv1.Columns[indiceCampo].ValueType.ToString();
              if(tipocampo.Trim()=="System.Int32")
              {
                  cmbParam.Items.Clear();
                  cmbParam.Items.Add("=");
                  cmbParam.Items.Add(">");
                  cmbParam.Items.Add(">=");
                  cmbParam.Items.Add("<");
                  cmbParam.Items.Add("<=");
                  cmbParam.Items.Add("<>");
              }
              else if (tipocampo.Trim() == "System.String")
              {
                  cmbParam.Items.Clear();
                  cmbParam.Items.Add("=");
                  cmbParam.Items.Add("Começa com");
                  cmbParam.Items.Add("Termina em");
                  cmbParam.Items.Add("Tem a palavra");
              }
              else
              {
                  MessageBox.Show("Implemente Código para outros tipos");
              }
          }

OBS do Autor: Veja que não implementei para todos os tipos de dados, apenas para os tipos mais comuns. Int e string, fica para você implementar para os demais tipos usados.

20) Para finalizar o conteúdo desse artigo, vamos ao código que responderá ao evento click do Botão filtrar.

private void btnFiltrar_Click(object sender, EventArgs e)
          {
              string campo = cmbCampo.Text;
              string parametro = cmbParam.Text;
              string valor = txtBusca.Text;
              int indiceCampo = cmbCampo.SelectedIndex;
              string tipocampo = this.dgv1.Columns[indiceCampo].ValueType.ToString();
              //Para tipos String
              if(tipocampo=="System.String")
              {
                  if(parametro=="Tem a palavra")
                  {
                      parametro= "Like ";
                      valor = "'%" + valor + "%'"; 
                  }
                  else if(parametro=="=")
                  {
                      parametro= "=";
                      valor = "'" + valor + "'";
                  }
                  else if(parametro=="Começa com")
                  {
                      parametro= "Like ";
                      valor = "'" + valor + "%'";
                  }
                  else if (parametro=="Termina em")
                  {
                      parametro = "Like ";
                      valor = "'%" + valor + "'";
                  }
              }
              //Para tipos int não são necessário ajustes.
              string csql = "Select * from " + this.Tag.ToString() +
                  " where " + campo + " " + parametro + " " + valor;
              clsDados busca = new clsDados();
              DataSet ds = busca.RetornarDataSet(csql);
              this.dgv1.DataSource = ds.Tables[0];
          }

Note que esse formulário de pesquisa poderá ser utilizado por qualquer formulário de cadastro, sem alterações. Você pode melhorar o código com o tratamento para os outros tipos de dados como data e hora por exemplo.

Com isso temos a camada de apresentação, onde foram criados os formulários para cadastro de dados do cliente e um formulário de pesquisa genérico que pode ser utilizado em toda a aplicação. Essa camada faz a interface com a camada intermediária, em sua maior parte com a lógica de negócios, entretanto no caso específico do formulário de pesquisa (por ser “generalista”) a interface é feita direta com a lógica do controlador através do método RetornaDataSet da classe clsDados.

Apólice de Seguros

Estudaremos mais sobre o Projeto de Apólice de Seguros, de forma geral. Observe a Figura 22 - Diagrama ER Numerado.

Diagrama ER Numerado
Figura 22 - Diagrama ER Numerado

A tabela de apólices é sem dúvida a mais importante do Sistema e para que possa ser feito o cadastro de uma nova apólice inicialmente temos que possuir dados nas tabelas de clientes (tbCliente) [não numerada pois nos artigos anteriores implementamos a funcionalidade para a mesma] temos que ter os dados já cadastrados na tabela de modelo de carros (tbModelo) [6] e a partir da apólice cadastrada gerar as parcelas [5] para o pagamento por parte do cliente. Já em relação aos sinistros ocorridos [2] para que possa ser cadastrado, inicialmente temos que ter também a apólice cadastrada [1] e previamente cadastrados os tipos de danos que podem ocorrer [3] e os tipos de sinistros já cadastrados. Vamos criar a lógica de negócios e a respectiva camada de apresentação para as informações auxiliares da apólice. Nessa ordem: Dano, Tipo de Sinistro, e Modelos de Carros.

1) Com o aplicativo aberto adicione três novas classes chamadas respectivamente: clnDanos.cs, clnTipos.cs, clnModelos.cs, conforme Figura 23:

Outras Classes
Figura 23 - Outras Classes

2) Agora adicione na Pasta [Camada Apresentacao] três novos formulários com os nomes respectivamente: FrmDanos.cs, FrmTipos.cs e FrmModelos.cs, como mostra a Figura 24.

Outros Formulários
Figura 24 - Outros Formulários

Vamos montar a interface com o usuário nesses três formulários. Para tanto acrescente os controles e modifique os nomes conforme solicitado:

3) Alterne para o formulário FrmDados e crie essa interface, dê o nome para os controles em azul, como mostra a Figura 25.

FrmDanos.cs
Figura 25 - FrmDanos.cs

Obs: Como boa prática utilize os mesmo padrão de nomes para os botões de comando.

4) Alterne para o formulário FrmTipos e crie essa interface, dê o nome para os controles em azul (Figura 26).

FrmTipos.cs
Figura 26 - FrmTipos.cs

5) Alterne para o formulário FrmModelos e crie essa interface, dê o nome para os controles em azul (Figura 27).

FrmModelos
Figura 27 – FrmModelos

Lógica de Negócios das classes criadas

Como a lógica é idêntica a apresentada nos artigos anteriores. Aqui será apresentado apenas o código de cada classe. Acredita-se ser desnecessário o detalhamento, pois é considerado que o leitor tenha feito a aplicação até o presente.

Abaixo temos a classe clnDados até com as declaração dos namespaces. Copie e cole o código, mas não deixe de analisá-lo novamente:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
    class clnDanos
    {
        //1 - Campos privados a classe
        private int idDano;
        private string descDano;
        //2 - propriedades, acesso aos campos privados
        public int IdDano
        {
            get { return idDano; }
            set { idDano = value; }
        }
        public string DescDano
        {
            get { return descDano; }
            set { descDano = value; }
        }
        //3 - métodos da classe de Negócios (clnDanos.cs)
        //3.1 Buscar dados de danos cujo codigo foi especificado
        public void Buscar()
        {
            string csql;
            csql = "Select * From tbDano where idDano=" + IdDano;
            DataSet ds;
            clsDados seguros = new clsDados();
            ds = seguros.RetornarDataSet(csql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                Array dados = ds.Tables[0].Rows[0].ItemArray;
                idDano = Convert.ToInt16(dados.GetValue(0));
                descDano  = Convert.ToString(dados.GetValue(1));
            }
        }
        //3.2 Buscar o próximo Id Numerico para
        //inclusao de um novo tipo de dano.
        public int BuscarId()
        {
            string csql;
            csql = "Select Top 1 (idDano) From tbDano order by idDano desc";
            int IdBuscado;
            clsDados seguros = new clsDados();
            IdBuscado = seguros.RetornarIdNumerico(csql);
            return IdBuscado;
        }
        //3.3 Método para incluir um novo tipo de dano no
        //Banco de dados
        public void Gravar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Insert into tbDano");
            csql.Append("(");
            csql.Append("idDano,");
            csql.Append("descDano) Values(");
            csql.Append(idDano);
            csql.Append(",'" + descDano + "')");
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
        //3.4 Método para atualizar (alterar um registro)
        public void Atualizar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Update tbDano ");
            csql.Append("set idDano=");
            csql.Append(idDano);
            csql.Append(", descDano='");
            csql.Append(descDano);
            csql.Append("' where idDano=");
            csql.Append(IdDano);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
        //3.5 Método para excluir um dano do
        //Banco de dados
        public void Excluir()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Delete From tbDano ");
            csql.Append(" where idDano=");
            csql.Append(IdDano);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
        //3.6 Método Buscar todos os Danos
        public DataSet BuscarTodos()
        {
            string csql;
            csql = "Select * From tbDano order by descDano";
            DataSet ds;
           clsDados seguros = new clsDados();
           ds = seguros.RetornarDataSet(csql);
           return ds;
         }
     }
}

Abaixo classe: clnTipos

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
 
namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
    class clnTipos
    {
        //1 - Campos privados a classe
        private int idTipo;
        private string descTipo;
 
        //2 - propriedades, acesso aos campos privados
        public int IdTipo
        {
            get { return idTipo; }
            set { idTipo = value; }
        }
        public string DescTipo
        {
            get { return descTipo; }
            set { descTipo = value; }
        }
 
        //3 - métodos da classe de Negócios (clnTipos.cs)
 
        //3.1 Buscar dados de tipos cujo codigo foi especificado
        public void Buscar()
        {
            string csql;
            csql = "Select * From tbTipo where idTipo=" + IdTipo;
            DataSet ds;
            clsDados seguros = new clsDados();
            ds = seguros.RetornarDataSet(csql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                Array dados = ds.Tables[0].Rows[0].ItemArray;
                idTipo = Convert.ToInt16(dados.GetValue(0));
                descTipo = Convert.ToString(dados.GetValue(1));
            }
        }
 
        //3.2 Buscar o próximo Id Numerico para
        //inclusao de um novo tipo.
        public int BuscarId()
        {
            string csql;
            csql = "Select Top 1 (idTipo) From tbTipo order by idTipo desc";
            int IdBuscado;
            clsDados seguros = new clsDados();
            IdBuscado = seguros.RetornarIdNumerico(csql);
            return IdBuscado;
        }
 
        //3.3 Método para incluir um novo tipo no
        //Banco de dados
        public void Gravar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Insert into tbTipo");
            csql.Append("(");
            csql.Append("idTipo,");
            csql.Append("descTipo) Values(");
            csql.Append(idTipo);
            csql.Append(",'" + descTipo + "')");
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
 
        //3.4 Método para atualizar (alterar um registro)
        public void Atualizar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Update tbTipo ");
            csql.Append("set idTipo=");
            csql.Append(idTipo);
            csql.Append(", descTipo='");
            csql.Append(descTipo);
            csql.Append("' where idTipo=");
            csql.Append(idTipo);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
 
        //3.5 Método para excluir um tipo do
        //Banco de dados
        public void Excluir()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Delete From tbTipo ");
            csql.Append(" where idTipo=");
            csql.Append(idTipo);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
      //3.6 Método Buscar todos os Tipos
      public DataSet BuscarTodos()
     {
            string csql;
            csql = "Select * From tbTipo order by descTipo";
            DataSet ds;
           clsDados seguros = new clsDados();
           ds = seguros.RetornarDataSet(csql);
           return ds;
      }
    }
}

Abaixo classe: clnModelos

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
 
namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios
{
    class clnModelos
    {
        //1 - Campos privados a classe
        private int idModelo;
        private string descModelo;
        private string descMarca;
 
        //2 - propriedades, acesso aos campos privados
        public int IdModelo
        {
            get { return idModelo; }
            set { idModelo = value; }
        }
        public string DescModelo
        {
            get { return descModelo; }
            set { descModelo = value; }
        }
        public string DescMarca
        {
            get { return descMarca; }
            set { descMarca = value; }
        }
 
        //3 - métodos da classe de Negócios (clnModelos.cs)
        //3.1 Buscar dados de Modelos cujo codigo foi especificado
        public void Buscar()
        {
            string csql;
            csql = "Select * From tbModelo where idModelo=" + IdModelo;
            DataSet ds;
            clsDados seguros = new clsDados();
            ds = seguros.RetornarDataSet(csql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                Array dados = ds.Tables[0].Rows[0].ItemArray;
                idModelo = Convert.ToInt16(dados.GetValue(0));
                descModelo = Convert.ToString(dados.GetValue(1));
                descMarca = Convert.ToString(dados.GetValue(2));
            }
        }
 
        //3.2 Buscar o próximo Id Numerico para
        //inclusao de um novo modelo.
        public int BuscarId()
        {
            string csql;
            csql = "Select Top 1 (idModelo) From tbModelo order by idModelo desc";
            int IdBuscado;
            clsDados seguros = new clsDados();
            IdBuscado = seguros.RetornarIdNumerico(csql);
            return IdBuscado;
        }
 
        //3.3 Método para incluir um novo modelo no
        //Banco de dados
        public void Gravar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Insert into tbModelo");
            csql.Append("(");
            csql.Append("idModelo,");
            csql.Append("descModelo,");
            csql.Append("descMarca) Values(");
            csql.Append(idModelo);
            csql.Append(",'" + descModelo + "'");
            csql.Append(",'" + descMarca + "')");
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
 
        //3.4 Método para atualizar (alterar um registro)
        public void Atualizar()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Update tbModelo ");
            csql.Append("set idModelo=");
            csql.Append(idModelo);
            csql.Append(", descModelo='");
            csql.Append(descModelo);
            csql.Append("', descMarca='");
            csql.Append(descMarca);
            csql.Append("' where idModelo=");
            csql.Append(idModelo);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
 
        //3.5 Método para excluir um dano do
        //Banco de dados
        public void Excluir()
        {
            StringBuilder csql = new StringBuilder();
            csql.Append("Delete From tbModelo ");
            csql.Append(" where idModelo=");
            csql.Append(idModelo);
            clsDados seguros = new clsDados();
            seguros.ExecutarComando(csql.ToString());
        }
 
    }
}

Camada de Apresentação

Bom, vamos agora a camada de apresentação. Seria interessante, você copiar os código para dentro de cada evento (um a um) ou se copiar o código do formulário não se esqueça de instanciar os eventos na inicialização do formulário. Siga minha dica depois confira com o código aqui colocado.

Formulário: FrmDanos

Abaixo código completo com todos os eventos e métodos declarados: using System;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Seguros_OO.Camada_Intermediaria.Logica_Negocios;
 
namespace Seguros_OO.Camada_Apresentacao
{
    public partial class FrmDanos : Form
    {
        public FrmDanos()
        {
            InitializeComponent();
        }
 
        //Método público para limpar caixas de texto
        public void LimparTxt(Control controles)
        {
            foreach (Control ctl in controles.Controls)
            {
                if (ctl is TextBox) ctl.Text = "";
            }
        }
 
        private void btnIncluir_Click(object sender, EventArgs e)
        {
            try
            {
                clnDanos dano = new clnDanos();
                //Dispara o método para buscar o IdDano
                dano.IdDano = dano.BuscarId();
                dano.DescDano = txtdescDano.Text;
                dano.Gravar();
                string mensagem = "Registro Dano: " +
                    dano.IdDano + "\nDescrição: " + dano.DescDano +
                    "\nGravado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnIncluir.Enabled = false;
                btnCancelar.Enabled = false;
                txtidDano.Enabled = true;
                txtidDano.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
 
        }
 
        private void btnAtualizar_Click(object sender, EventArgs e)
        {
            try
            {
                clnDanos dano = new clnDanos();
                dano.IdDano = int.Parse(txtidDano.Text);
                dano.DescDano = txtdescDano.Text;
                string mensagem = "Registro Dano: " +
                    dano.IdDano + "\nNome: " + dano.DescDano +
                    "\nAlterado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnAtualizar.Enabled = false;
                btnCancelar.Enabled = false;
                btnExcluir.Enabled = false;
                txtidDano.Enabled = true;
                txtidDano.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
 
 
        }
 
        private void btnExcluir_Click(object sender, EventArgs e)
        {
            string pergunta;
            pergunta = "Deseja excluir o dado: \n" +
                txtidDano.Text + ": " + txtdescDano.Text +
                "  ?";
            int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Atenção",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question));
            if (ret == 6)
            {
                clnDanos dano = new clnDanos();
                dano.IdDano = int.Parse(txtidDano.Text);
                dano.DescDano = txtdescDano.Text;
                dano.Excluir();
                string mensagem = "Registro Dano: " +
                    dano.IdDano + "\nDescrição: " + dano.DescDano +
                    "\nExcluído com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnAtualizar.Enabled = false;
                btnCancelar.Enabled = false;
                btnExcluir.Enabled = false;
                txtidDano.Enabled = true;
                txtidDano.Focus();
            }
            else
            {
                MessageBox.Show("Operação Cancelada",
                    "Cancelada", MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
 
        }
 
        private void btnCancelar_Click(object sender, EventArgs e)
        {
            LimparTxt(groupBox1);
            btnIncluir.Enabled = false;
            btnAtualizar.Enabled = false;
            btnCancelar.Enabled = false;
            btnExcluir.Enabled = false;
            txtidDano.Enabled = true;
            txtidDano.Focus();
        }
 
        private void btnSair_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
        private void btnProcurar_Click(object sender, EventArgs e)
        {
            FrmPesquisa f = new FrmPesquisa();
            f.Text = "Consulta Tipos de Danos";
            f.Tag = "tbDano"; //nome da tabela (macete)  :)
            f.ShowDialog();
        }
 
        private void txtidDano_Leave(object sender, EventArgs e)
        {
            int vidDano = 0;
            if (txtidDano.Text.Trim() != "")
            {
                vidDano = int.Parse(txtidDano.Text);
            }
            clnDanos dano = new clnDanos();
            dano.IdDano = vidDano;
            dano.Buscar();
            if (dano.DescDano == null)
            {
                //preparando para inclusao
                LimparTxt(groupBox1);
                txtidDano.Text = "";
                txtidDano.Enabled = false;
                btnIncluir.Enabled = true;
                btnCancelar.Enabled = true;
            }
            else
            {
                //preparando para alteracao
                LimparTxt(groupBox1);
                txtidDano.Enabled = false;
                txtidDano.Text = Convert.ToString(dano.IdDano);
                txtdescDano.Text = Convert.ToString(dano.DescDano);
                btnAtualizar.Enabled = true;
                btnCancelar.Enabled = true;
                btnExcluir.Enabled = true;
            }
        }
    }
}

Formulário: FrmTipos

Abaixo código completo com todos os eventos e métodos declarados:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Seguros_OO.Camada_Intermediaria.Logica_Negocios;
 
namespace Seguros_OO.Camada_Apresentacao
{
    public partial class FrmTipos : Form
    {
        public FrmTipos()
        {
            InitializeComponent();
        }
        //Método público para limpar caixas de texto
        public void LimparTxt(Control controles)
        {
            foreach (Control ctl in controles.Controls)
            {
                if (ctl is TextBox) ctl.Text = "";
            }
        }
 
        private void btnIncluir_Click(object sender, EventArgs e)
        {
            try
            {
                clnTipos tipo = new clnTipos();
                //Dispara o método para buscar o IdTipo
                tipo.IdTipo = tipo.BuscarId();
                tipo.DescTipo = txtdescTipo.Text;
                tipo.Gravar();
                string mensagem = "Registro Tipo: " +
                    tipo.IdTipo + "\nDescrição: " + tipo.DescTipo +
                    "\nGravado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnIncluir.Enabled = false;
                btnCancelar.Enabled = false;
                txtidTipo.Enabled = true;
                txtidTipo.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
 
        }
 
        private void btnAtualizar_Click(object sender, EventArgs e)
        {
            try
            {
                clnTipos tipo = new clnTipos();
                tipo.IdTipo = int.Parse(txtidTipo.Text);
                tipo.DescTipo = txtdescTipo.Text;
                string mensagem = "Registro Dano: " +
                    tipo.IdTipo + "\nNome: " + tipo.DescTipo +
                    "\nAlterado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnAtualizar.Enabled = false;
                btnCancelar.Enabled = false;
                btnExcluir.Enabled = false;
                txtidTipo.Enabled = true;
                txtidTipo.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
 
 
        }
 
        private void btnExcluir_Click(object sender, EventArgs e)
        {
            string pergunta;
            pergunta = "Deseja excluir o tipo: \n" +
                txtidTipo.Text + ": " + txtdescTipo.Text +
                "  ?";
            int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Atenção",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question));
            if (ret == 6)
            {
                clnTipos tipo = new clnTipos();
                tipo.IdTipo = int.Parse(txtidTipo.Text);
                tipo.DescTipo = txtdescTipo.Text;
                tipo.Excluir();
                string mensagem = "Registro Tipo: " +
                    tipo.IdTipo + "\nDescrição: " + tipo.DescTipo +
                    "\nExcluído com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnAtualizar.Enabled = false;
                btnCancelar.Enabled = false;
                btnExcluir.Enabled = false;
                txtidTipo.Enabled = true;
                txtidTipo.Focus();
            }
            else
            {
                MessageBox.Show("Operação Cancelada",
                    "Cancelada", MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
 
        }
 
        private void btnCancelar_Click(object sender, EventArgs e)
        {
            LimparTxt(groupBox1);
            btnIncluir.Enabled = false;
            btnAtualizar.Enabled = false;
            btnCancelar.Enabled = false;
            btnExcluir.Enabled = false;
            txtidTipo.Enabled = true;
            txtidTipo.Focus();
        }
 
        private void btnSair_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
        private void btnProcurar_Click(object sender, EventArgs e)
        {
            FrmPesquisa f = new FrmPesquisa();
            f.Text = "Consulta de Tipos de Sinistros";
            f.Tag = "tbTipo"; //nome da tabela (macete)  :)
            f.ShowDialog();
        }
 
        private void txtidTipo_Leave(object sender, EventArgs e)
        {
            int vidtipo = 0;
            if (txtidTipo.Text.Trim() != "")
            {
                vidtipo = int.Parse(txtidTipo.Text);
            }
            clnTipos tipo = new clnTipos();
            tipo.IdTipo = vidtipo;
            tipo.Buscar();
            if (tipo.DescTipo == null)
            {
                //preparando para inclusao
                LimparTxt(groupBox1);
                txtidTipo.Text = "";
                txtidTipo.Enabled = false;
                btnIncluir.Enabled = true;
                btnCancelar.Enabled = true;
            }
            else
            {
                //preparando para alteracao
                LimparTxt(groupBox1);
                txtidTipo.Enabled = false;
                txtidTipo.Text = Convert.ToString(tipo.IdTipo);
                txtdescTipo.Text = Convert.ToString(tipo.DescTipo);
                btnAtualizar.Enabled = true;
                btnCancelar.Enabled = true;
                btnExcluir.Enabled = true;
            }
 
        }
     }
}

Formulário: FrmModelos

Abaixo código completo com todos os eventos e métodos declarados:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Seguros_OO.Camada_Intermediaria.Logica_Negocios;
 
namespace Seguros_OO.Camada_Apresentacao
{
    public partial class FrmModelos : Form
    {
        public FrmModelos()
        {
            InitializeComponent();
        }
        //Método público para limpar caixas de texto
        public void LimparTxt(Control controles)
        {
            foreach (Control ctl in controles.Controls)
            {
                if (ctl is TextBox) ctl.Text = "";
            }
        }
        private void txtidModelo_Leave(object sender, EventArgs e)
        {
            int vidmodelo = 0;
            if (txtidModelo.Text.Trim() != "")
            {
                vidmodelo = int.Parse(txtidModelo.Text);
            }
            clnModelos modelo= new clnModelos();
            modelo.IdModelo = vidmodelo;
            modelo.Buscar();
            if (modelo.DescModelo == null)
            {
                //preparando para inclusao
                LimparTxt(groupBox1);
                txtidModelo.Text = "";
                txtidModelo.Enabled = false;
                btnIncluir.Enabled = true;
                btnCancelar.Enabled = true;
            }
            else
            {
                //preparando para alteracao
                LimparTxt(groupBox1);
                txtidModelo.Enabled = false;
                txtidModelo.Text = Convert.ToString(modelo.IdModelo);
                txtdescModelo.Text = Convert.ToString(modelo.DescModelo);
                txtdescMarca.Text = Convert.ToString(modelo.DescMarca);
                btnAtualizar.Enabled = true;
                btnCancelar.Enabled = true;
                btnExcluir.Enabled = true;
            }
 
        }
 
        private void btnIncluir_Click(object sender, EventArgs e)
        {
            try
            {
                clnModelos modelo = new clnModelos();
                //Dispara o método para buscar o idModelo
                modelo.IdModelo = modelo.BuscarId();
                modelo.DescModelo = txtdescModelo.Text;
                modelo.DescMarca = txtdescMarca.Text;
                modelo.Gravar();
                string mensagem = "Registro Modelo: " +
                    modelo.IdModelo + "\nDescrição: " + modelo.DescModelo +
                    "\nGravado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnIncluir.Enabled = false;
                btnCancelar.Enabled = false;
                txtidModelo.Enabled = true;
                txtidModelo.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
 
        }
 
        private void btnAtualizar_Click(object sender, EventArgs e)
        {
            try
            {
                clnModelos modelo = new clnModelos();
                modelo.IdModelo = int.Parse(txtidModelo.Text);
                modelo.DescModelo=  txtdescModelo.Text;
                modelo.DescMarca = txtdescMarca.Text;
                modelo.Atualizar();
                string mensagem = "Registro Modelo: " +
                    modelo.IdModelo + "\nNome: " + modelo.DescModelo +
                    "\nAlterado com sucesso";
                MessageBox.Show(mensagem, "Sucesso",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                LimparTxt(groupBox1);
                btnAtualizar.Enabled = false;
                btnCancelar.Enabled = false;
                btnExcluir.Enabled = false;
                txtidModelo.Enabled = true;
                txtidModelo.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro");
            }
        }
 
        private void btnExcluir_Click(object sender, EventArgs e)
        {
            try
            {
                string pergunta;
                pergunta = "Deseja excluir o modelo: \n" +
                    txtidModelo.Text + ": " + txtdescModelo.Text +
                    "  ?";
                int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Atenção",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question));
                if (ret == 6)
                {
                    clnModelos modelo = new clnModelos();
                    modelo.IdModelo = int.Parse(txtidModelo.Text);
                    modelo.DescModelo = txtdescModelo.Text;
                    modelo.Excluir();
                    string mensagem = "Registro Dano: " +
                        modelo.IdModelo + "\nDescrição: " + modelo.DescModelo +
                        "\nExcluído com sucesso";
                    MessageBox.Show(mensagem, "Sucesso",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    LimparTxt(groupBox1);
                    btnAtualizar.Enabled = false;
                    btnCancelar.Enabled = false;
                    btnExcluir.Enabled = false;
                    txtidModelo.Enabled = true;
                    txtidModelo.Focus();
                }
                else
                {
                    MessageBox.Show("Operação Cancelada",
                        "Cancelada", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                }
            }
            catch(Exception ex)
            {
                    MessageBox.Show("Não foi possível excluir, aconteceu " +
                    " o seguinte erro: "+ ex.Message.ToString());
            }
         }
      
        private void btnCancelar_Click(object sender, EventArgs e)
        {
            LimparTxt(groupBox1);
            btnIncluir.Enabled = false;
            btnAtualizar.Enabled = false;
            btnCancelar.Enabled = false;
            btnExcluir.Enabled = false;
            txtidModelo.Enabled = true;
            txtidModelo.Focus();
        }
 
        private void btnProcurar_Click(object sender, EventArgs e)
        {
            FrmPesquisa f = new FrmPesquisa();
            f.Text = "Consulta Tipos de Danos";
            f.Tag = "tbModelo"; //nome da tabela (macete)  :)
            f.ShowDialog();
        }
 
        private void btnSair_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
    }
}

Como vimos, a tabela de apólices é considerada a mais importante do Sistema e para que possa ser feito o cadastro de uma nova apólice, precisamos de alguns dados auxiliares. Estes dados poderão ser cadastrados a partir das classes que representam a lógica de negócios e a respectiva camada de apresentação criadas durante este artigo. Respectivamente: Dano, Tipo de Sinistro, e Modelos de Carros.