Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
1
Arquitetura em três camadas – Parte 2 [Acesso a Dados]
Esse post é para dar sequência no post “Arquitetura em três camadas – Parte 1 [conceito]”,
mostrando um pouco mais a fundo a parte de Acesso a Dados.
Quem não viu o post anterior, é fundamental dar uma lida antes de continuar lendo este.
Para começar
Como eu disse no post anterior, a arquitetura em camadas não é em cima de quantos projetos
uma solution tem, e sim na forma como ela está divida.
Eu, particularmente, gosto que as classes que serão objetos fiquem separadas de qualquer
classe que conterá métodos com regra de negócio. A maioria dos desenvolvedores e empresas
fazem os métodos de negócio dentro do objeto. Também é uma opção, mas eu não o farei.
Então, eu acrescentei outro projeto na Solution, onde ficará apenas os objetos:
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
2
Agora com todos os projetos criados, antes de qualquer coisa é importante fazermos o
relacionamento entre as camadas, referenciando as DLLs dos projetos. A relação entre as
camadas fica assim:
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
3
A camada de Acesso a Dados precisa unicamente da de Entidades. A de Regra de Negócio
precisa da de Entidades e da Acesso a Dados, a Web precisa da Entidades e Regra de Negócio,
e a Entidades não precisa de nenhuma DLL. No decorrer do post você entenderá o porque.
Obs.: Para adicionar as referência, basta você clicar com o botão direito em cima da pasta
“References” e clicar em “Add Reference...”. Lá você tem as opções de adicionar referências de
um projeto da solution, de adicionar referências nativas do .NET, e até mesmo de procurar
uma DLL em seu computador.
Camada de Acesso a Dados
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
4
Como falamos no post anterior: “É responsável pela persistência e acesso aos dados da
aplicação. Ela isola o resto da aplicação do meio de armazenamento usado de maneira que, se
o meio de armazenamento for trocado, apenas as classes desta camada precisarão ser
modificadas ou substituídas.”.
Em cima desse conceito, vamos começar a desenvolver a classe AD_Usuario.cs, criando
métodos básicos como: Listar, Retornar, Salvar e Excluir; fazendo acesso ao Banco de Dados,
para em um próximo post sobre a camada de Regra de Negócio, fazermos essa ponte entre a
Camada de Acesso a Dados e a Camada de Apresentação (Web). Então, vamos lá!
Antes de começarmos a desenvolver, vamos criar a tabela Usuário no Banco de Dados:
Criei uma tabela bem simples, só para exemplo. Coloquei a nomenclatura “ACE_” na frente do
nome da tabela, pois tenho costume de modularizar. Isso significa que essa tabela Usuário é
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
5
do módulo de Acesso do sistema. É um padrão meu; fica por sua conta seguir a mesma ideia
ou não.
Tabela criada, vamos para o Visual Studio.
Antes de mais nada, temos que adicionar a Connection String de conexão do Banco de Dados
no arquivo web.config do projeto. Dentro da tag <configuration>, adicione o seguinte código:
<connectionStrings>
<add name="NomeDaConnectionString" connectionString="Data
Source=DataSourceDoBD;Initial Catalog=NomeDaDatabaseDoBD;Persist
Security Info=True;User ID=UsuarioDoBD;Password=SenhaDoBD”
providerName="System.Data.SqlClient" />
</connectionStrings>
Obviamente que, trocando essas informações com dados reais da sua conexão. Aqui foi
somente para ilustrar.
Depois, devemos adicionar as seguintes referências que fazem conexão com o Banco de Dados
na classe AD_Usuario.cs:
using System.Data.SqlClient; using System.Data;
Adicione também nas referências do projeto a DLL nativa do .NET “System.Configuration”, pois
como vamos acessar o web.config para resgatar essa Connection String, também será
necessária:
using System.Configuration;
E também a referência com a camada de Entidades. Afinal, trabalharemos com os objetos:
using Camadas.Entidades;
Agora sim, vamos começar a desenvolver os métodos.
Desenvolvimento
Alguns métodos retornaram um DataReader/DataSet da consulta. Como estamos trabalhando
com objetos, temos que transformar esse retorno no objeto desejado. Para começar, temos
que criar o objeto Usuário, através da classe EN_Usuario do projeto Entidades:
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
6
namespace Camadas.Entidades { public class EN_Usuario { #region Atributos private int id; private string usuario; private string senha; private bool status; #endregion #region Propriedades public int Id { get { return id; } set { id = value; } } public string Usuario { get { return usuario; } set { usuario = value; } } public string Senha { get { return senha; } set { senha = value; } } public bool Status { get { return status; } set { status = value; } } #endregion } }
Reparem que as propriedades são exatamente iguais as colunas da tabela criada no Banco de
Dados.
Obs.: Eu tenho o costume de separar os códigos por regions. O código fica mais limpo e
organizado. Fica por sua conta usar ou não.
Com o objeto criado, voltamos para a classe AD_Usuario, do projeto de Acesso a Dados, para
fazermos essa transformação:
namespace Camadas.AcessoDados { public class AD_Usuario {
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
7
#region Construtor public EN_Usuario Construtor(SqlDataReader dr) { if (dr == null) { throw new ArgumentNullException("reader"); } int id = dr.GetOrdinal("id"); int usuario = dr.GetOrdinal("usuario"); int senha = dr.GetOrdinal("senha"); int status = dr.GetOrdinal("status"); EN_Usuario objUsuario = new EN_Usuario(); //Recuperando campos do retorno do objeto if (!dr.IsDBNull(id)) { objUsuario.Id = dr.GetInt32(id); } if (!dr.IsDBNull(usuario)) { objUsuario.Usuario = dr.GetString(usuario); } if (!dr.IsDBNull(senha)) { objUsuario.Senha = dr.GetString(senha); } if (!dr.IsDBNull(status)) { objUsuario.Status = dr.GetBoolean(status); } return objUsuario; } #endregion } }
O mérito aqui não é explicar o que o código faz, e sim mostrar como funciona as camadas.
Então, não explicarei a fundo este código, afinal, tem mais de uma forma de fazer. Essa é a que
eu mais gostei. Apenas entendam que o método está recebendo um DataReader e está
convertendo suas informações para o Objeto EN_Usuario. Reparem que os nomes das colunas,
resgatados pelo “dr.GetOrdinal()” é exatamente iguais as do Banco de Dados. Tem que ser
assim.
Agora vamos aos métodos. Embaixo do region Construtor, adicione o region Métodos, e
dentro dele adicione os métodos a seguir:
/// <summary> /// Método responsável pelo retorno dos Usuarios existentes /// </summary> /// <returns>Lista de Objetos EN_Usuario preenchidos</returns> public List<EN_Usuario> Listar() { SqlConnection conn = new SqlConnection();
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
8
conn.ConnectionString = ConfigurationManager.ConnectionStrings["NomeDaConnectionString"].ConnectionString; SqlCommand cmd = conn.CreateCommand(); cmd.CommandType = CommandType.Text; cmd.CommandText = @"SELECT id, usuario, senha, status FROM ACE_Usuario"; EN_Usuario objUsuario = new EN_Usuario(); List<EN_Usuario> lstUsuarioes = new List<EN_Usuario>(); try { conn.Open(); SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { objUsuario = this.Construtor(dr); lstUsuarioes.Add(objUsuario); } conn.Close(); } catch (Exception) { throw; } return lstUsuarioes; }
Uma explicação rápida de como as coisas funcionam, que serve para todos os métodos que
estarão nesse post:
- O “summary” que está em verde e cinza em cima do método é um comentário sobre o que o
método faz. Quando você instancia-lo, vai aparecer essa explicação para o desenvolvedor; o
que poderá ajuda-lo a entender qual método faz o que ele necessita. Também não é
obrigatório; vai de você resolver se vai usar no seu projeto ou não;
- No começo do método é necessário abrir conexão com o Banco de Dados. Para isso,
retornarmos a Connection String criada no web.config, através do código
“ConfigurationManager.ConnectionStrings["NomeDaConnectionString"].ConnectionStrin
g;”;
- Após isso, fazemos a query necessária dentro do SqlCommand, já integrada com a
Connection String desejada;
- Depois abrimos, de fato, a conexão com o Banco de Dados (conn.Open()), dentro de um
Try/catch, caso dê algum erro; executamos a query que está no SqlCommand; retornamos um
DataReader, e chamamos o método Contrutor() que faz a conversão para o objeto; atribuímos
o retorno do método no objeto EN_Usuario; e fechamos a conexão (conn.Close()).
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
9
Obs.: No caso do listar, retorna uma Lista de Objetos. Por isso tem um “while” no retorno da
consulta, e retorna um List<EN_Usuario>.
Vamos dar sequencia aos métodos:
/// <summary> /// Método responsável pelo retorno do Usuario desejado /// </summary> /// <param name="id">id do Usuario</param> /// <returns>Objeto EN_Usuario preenchido</returns> public EN_Usuario RetornarUsuario(int id) { SqlConnection conn = new SqlConnection(); conn.ConnectionString = ConfigurationManager.ConnectionStrings["NomeDaConnectionString"].ConnectionString; SqlCommand cmd = conn.CreateCommand(); cmd.CommandType = CommandType.Text; cmd.CommandText = @"SELECT id, usuario, senha, status FROM ACE_Usuario WHERE id = @id"; cmd.Parameters.Add("@id", SqlDbType.Int, 10); cmd.Parameters[0].Value = id; EN_Usuario objUsuario = new EN_Usuario(); try { conn.Open(); SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) { objUsuario = this.Construtor(dr); } conn.Close(); } catch (Exception) { throw; } return objUsuario; } /// <summary> /// Método responsável por Salvar o Usuario no Banco de Dados /// Insere ou Altera /// </summary> /// <param name="objUsuario">objetoa Usuario preenchido</param> /// <returns>Id do Usuario</returns> public int Salvar(EN_Usuario objUsuario) { int idUsuario = 0;
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
10
SqlConnection conn = new SqlConnection(); conn.ConnectionString = ConfigurationManager.ConnectionStrings["NomeDaConnectionString"].ConnectionString; SqlCommand cmd = conn.CreateCommand(); cmd.CommandType = CommandType.Text; cmd.Parameters.Add("@usuario", SqlDbType.VarChar, 10); cmd.Parameters[0].Value = objUsuario.Usuario; cmd.Parameters.Add("@senha", SqlDbType.VarChar, 8); cmd.Parameters[1].Value = objUsuario.Senha; if (objUsuario.Id == 0) { cmd.CommandText = @"INSERT INTO ACE_Usuario (usuario ,senha ,status) VALUES (@usuario ,@senha ,'True') SELECT @@identity"; } else { cmd.CommandText = @"UPDATE ACE_Usuario SET usuario = @usuario ,senha = @senha WHERE id = @id SELECT @id"; cmd.Parameters.Add("@id", SqlDbType.Int); cmd.Parameters[2].Value = objUsuario.Id; } try { idUsuario = Convert.ToInt32(cmd.ExecuteScalar()); } catch (Exception) { throw; } return idUsuario; } /// <summary> /// Método responsável por Excluir o Usuario desejado /// </summary> /// <param name="id">id do Usuario</param> public void Excluir(int id) { SqlConnection conn = new SqlConnection(); conn.ConnectionString = ConfigurationManager.ConnectionStrings["NomeDaConnectionString"].ConnectionString;
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
11
SqlCommand cmd = conn.CreateCommand(); cmd.CommandType = CommandType.Text; cmd.CommandText = @"UPDATE ACE_Usuario SET status = 'False' WHERE id = @id"; cmd.Parameters.Add("@id", SqlDbType.Int); cmd.Parameters[0].Value = id; try { cmd.ExecuteNonQuery(); } catch (Exception) { throw; } }
Algumas observações:
- O método Salvar ele faz tanto o Insert quanto o Update, identificando se o Objeto passado
como parâmetro possui um Id maior que zero ou não. Assim não precisa fazer dois métodos
com o mesmo intuito, que é Salvar os dados no Banco de Dados. Ele retorna o id do usuário
incluído ou alterado, porque normalmente precisamos desse id quando estamos
desenvolvendo a camada de apresentação. Mas, fica a seu critério fazer o método desse jeito,
ou de outra forma;
- O método Excluir eu sempre atualizo o campo “status” no banco, fazendo uma exclusão
lógica, e não física do usuário. Caso você precise usá-lo mais para frente, ou até mesmo para
log, é melhor assim. Mas fica a seu critério ter essa coluna na tabela ou não. É uma questão de
necessidade e estratégia do projeto.
Finalização
A camada de Acesso a Dados é a que tem mais formas de ser desenvolvida. Aqui utilizamos o
ADO.NET nativo. Poderia ser desenvolvida utilizando outras formas como Linq, Linq to sql,
Entity Framework, Enterprise Library, etc. Fica a seu critério. Tem muitos artigos sobre na
internet, pesquisem.
Espero que tenham entendido como funciona a camada de Acesso a Dados da forma como eu
mostrei. No próximo post falarei sobre a camada de Regra de Negócio. Aguardem!
Abraços,
Marcela Mariotti Peres – http://marcelamperes.wordpress.com/ Arquitetura em três camadas – Parte 2 [Acesso a Dados]
12
Marcela Mariotti Peres