Pequeno cadastro com PostgreSQL, NHibernate e C#

Entendendo o NHibernate

NHibernate é uma das soluções de Mapeamento objeto-relacional (ORM) para a plataforma de desenvolvimento Microsoft .NET, um framework que fornece o mapeamento do modelo relacional para a orientação a objeto, auxiliando a ligação entre os dois.

Arquitetura

NHibernate-Arquitetura-208x300

Na primeira camada temos a representação da nossa aplicação. Nele temos nossas classes de domínio que serão mapeadas para o SGDB. É nesta camada que teremos também o mapeamento destas classes, que será passado para o NHibernate.

Na segunda camada, de cor laranja, temos a representação do NHibernate, com suas classes de gerenciamento de sessão e conexão. Nesta camada é interessante notar que o NHibernate não acessa diretamente a base de dados, mas faz uso da terceira camada para isso.

Esta terceira camada representa as abstrações de acesso a dados do .NET, ou seja, o NHibernate faz uso destas interfaces do ADO.NET para se comunicar com a base de dados. Sendo assim, qualquer SGDB que tenha uma implementação para o ADO.NET poderá ser utilizado com o NHibernate.

Por fim, na quarta camada temos o database de fato, onde os dados serão persistidos.

ISessionFactory – Classe responsável por criar as sessões do NHibernate e manter o mapeamento das classes em memória. É responsável também pelo cache de segundo nível. Este é o objeto mais caro do NHibernate e por este motivo é altamente recomendável que tenhamos apenas uma instância do mesmo em nossa aplicação.

ISession – Classe responsável por gerenciara comunicação entre a aplicação e a base de dados. É ela quem encapsula uma conexão com o ADO.NET connection, fornecendo métodos para persistência e manipulação de objetos, além de gerenciamento de transações com a base de dados. Nela fica o cache de primeiro nível do NHibernate.

ITransaction – Classe responsável por abstrair a ADO.NET Transaction, possibilitando o uso de transações atômicas para realização de operações na base de dados.

IConnectionProvider – Classe interna do NHibernate que serve como factory para ADO.NET connections e Commands. O objetivo dela é abstrair as implementações concretas das interfaces IDBConnection e IDBCommand.

IDriver – Classe que encapsula as diferenças entre os providers ADO.NET, como convenções para nomes de parâmetros e recursos suportados por cada SGDB.

TransactionFactory – Classe interna do NHibernate para criação de transações.

Persistindo dados com NHibernate

Crie uma “Solution Blank”  e dê o nome de NHibernate e clique no botão OK;

criar

 

Será criada uma solução vazia onde iremos adicionar nossos projetos (utilize a versão 4.5.1 do .Net Framework).

1 – Clicando com o botão direito sobre a Solution ‘Nhibernate‘, clique em Add -> New Project.

2 – Selecione a linguagem C#  e o template Class Library dê o nome de Repositorio e clique em OK.

repositorio

 

3 – Repita o passo 1, selecione a linguagem C#  e o template ASP.NET web Application dê o nome de Loja e clique em OK.

webLoja

 

4 – Na próxima janela selecione o template Empty  e clique em OK.

WebForm

 

Adicionando referências do NHibernate e do provedor Npgsql

No projeto Repositorio  adicione duas pastas, uma com o nome de Entidades e a outra com o nome de Mapeamento.

Para adicionar as referências, usaremos o Nuget e selecionaremos o projeto Repositorio.

    
Install-Package NHibernate
Install-Package Npgsql

Após adicionar as referências, vamos configurar o Web.config.

  
  
    
NHibernate.Connection.DriverConnectionProvider NHibernate.Dialect.PostgreSQL82Dialect Server=localhost;Port=5432;User ID=postgres;Password=postgres; Database=loja update true true

Criando as Entidades e o Mapeamento
Para criar o arquivo de mapeamento, clique com o botão direito na pasta Mapeamento, selecione Add -> New Item, selecione Data -> XML File.
Para o arquivo de mapeamento, temos que utilizar a extensão .hbm.xml após o nome do arquivo:
Ex.: nome_entidade.hbm.xml

mapeamento

Entidade

public class Produto
{
    public virtual int Id { get; set; }
    public virtual string Nome { get; set; }
    public virtual decimal Preco { get; set; }
    public virtual Categoria Categoria { get; set; }
}

Mapeamento



  
    
      
    
    
    
    
  

Entidade

public class Categoria
{
    public virtual int Id { get; set; }
    public virtual string Nome { get; set; }
    public virtual IList Produtos { get; set; }
}

Mapeamento



  
    
      
    
    
    
      
      
    
  

Uma informação importante é que para o NHibernate encontrar o mapeamento, o xml deve ser colocado dentro do código compilado do programa (Assembly do programa), porém o Visual Studio, por padrão, só coloca o código C# no Assembly gerado. Para mudar o comportamento padrão da compilação (build) do Visual Studio, precisamos configurar o Build Action do arquivo.
Clique com o botão direito sobre o arquivo e selecione Properties, e em Build Action selecione Embedded Resource.

build

Criando classes do Repositorio

A classe NHibernateHelper é responsável pela comunicação com o banco de dados.

public class NHibernateHelper
{
	private static ISessionFactory fabrica = CriaSessionFactory();

	private static ISessionFactory CriaSessionFactory()
	{
		Configuration cfg = RecuperaConfiguracao();
		return cfg.BuildSessionFactory();
	}
	public static Configuration RecuperaConfiguracao()
	{
		Configuration cfg = new Configuration();
		cfg.Configure();
		cfg.AddAssembly(Assembly.GetExecutingAssembly());
		return cfg;
	}

	public static void GeraSchema()
	{
		Configuration cfg = RecuperaConfiguracao();
		new SchemaExport(cfg).Create(true, true);
	}

	public static ISession AbreSession()
	{
		return fabrica.OpenSession();
	}
}

Clique com o botão direito sobre o projeto Repositorio, clique em Add -> New Item, selecione Interface, dê o nome de ICrudDAO.

public interface ICrudDAO
{
    void Inserir(T entidade, ISession session);
    void Alterar(T entidade, ISession session);
    void Excluir(T entidade, ISession session);
    T ConsultarPorId(int Id, ISession session);
    IList Listar();
}

Adicione uma nova classe no projeto Repositorio e dê o nome de CrudDAO, essa classe será responsável pela implementação da interface ICrudDAO.

public class CrudDAO : ICrudDAO where T : class
{
	public void Inserir(T entidade, ISession session)
	{
		using (ITransaction transacao = session.BeginTransaction())
		{
			try
			{
				session.Save(entidade);
				transacao.Commit();
			}
			catch (Exception ex)
			{
				if (!transacao.WasCommitted)
				{
					transacao.Rollback();
				}
				throw new Exception("Erro ao inserir Categoria : " + ex.Message);
			}
		}
	}
	public void Alterar(T entidade, ISession session)
	{
		using (ITransaction transacao = session.BeginTransaction())
		{
			try
			{
				session.Update(entidade);
				transacao.Commit();
			}
			catch (Exception ex)
			{
				if (!transacao.WasCommitted)
				{
					transacao.Rollback();
				}
				throw new Exception("Erro ao Alterar Categoria : " + ex.Message);
			}
		}
	}
	public void Excluir(T entidade, ISession session)
	{
		using (ITransaction transacao = session.BeginTransaction())
		{
			try
			{
				session.Delete(entidade);
				transacao.Commit();
			}
			catch (Exception ex)
			{
				if (!transacao.WasCommitted)
				{
					transacao.Rollback();
				}
				throw new Exception("Erro ao Excluir Categoria : " + ex.Message);
			}
		}
	}
	public T ConsultarPorId(int Id, ISession session)
	{
		return session.Get(Id);
	}
	public IList Listar()
	{
		using (ISession session = NHibernateHelper.AbreSession())
		{
			return session.Query().ToList();
		}
	}
}

Adicione uma nova classe no projeto Repositorio e dê o nome de CategoriaDAO, essa classe irá herdar toda implementação do CrudDAO.

public class CategoriaDAO : CrudDAO
{ 
}

No projeto Loja, adicione uma página WebForm(para realizarmos um pequeno teste), adicione os componentes pelo toolbox.

pagina

Dê dois cliques no botão Salvar e adicione o código abaixo:

public void Page_Load(object sender, EventArgs e)
{
	/*
	 * Cria as tabelas na base de dados.
	 * Comentar após executar pela primeira vez.
	 */
	NHibernateHelper.GeraSchema();
}

public void Button1_Click(object sender, EventArgs e)
{
	Categoria categoria = new Categoria();
	categoria.Nome = txt_categoria.Text;
        ISession session = NHibernateHelper.AbreSession();
        new CategoriaDAO().Inserir(categoria, session);
}

Agora é ir aprimorando seus testes.

Espero que tenham gostado, qualquer dúvida, crítica ou sugestão só deixar um comentário.

Abraço e até o próximo post.

Referências:
http://www.devmedia.com.br/nhibernate-arquitetura-fundamentos-e-recursos-revista-net-magazine-102/26942;
http://nhibernate.info/doc/nhibernate-reference/quickstart.html#quickstart-intro;
http://www.princiweb.com.br/blog/programacao/aspnet/veja-o-que-e-orm-e-os-frameworks-disponiveis-para-net.html;
http://www.macoratti.net/14/09/c_lpgnh1.htm;

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *