.NET

18 jul, 2016

ASP .NET MVC – CRUD com Fluent NHibernate – Parte 01

Publicidade

Neste artigo, vou mostrar como realizar as operações CRUD em uma aplicação ASP .NET MVC usando o NHibernate e realizando o mapeamento com o Fluent NHibernate.

Se você já chegou a usar o NHibernate e não conhece o Fluent NHibernate, deve saber que gerar os arquivos de mapeamento (.hbm) dá muito trabalho e é uma tarefa que esta sujeita a erros. Assim, se esse era um quesito que o desmotivava a usar o NHibernate, fique sabendo que agora você não tem mais essa desculpa.

O Fluent NHibernate chegou (há um bom tempo, por sinal) para auxiliar a realização dos mapeamentos das suas entidades com o seu banco de dados. Com ele podemos realizar o mapeamento via código sem ter que usar os arquivos .hbm.

Dessa forma, o Fluent NHibernate oferece uma alternativa aos arquivos de mapeamento XML padrão do NHibernate. Ao invés de escrever documentos XML (arquivos .hbm.xml), o Fluent NHibernate permite que você escreva mapeamentos fortemente tipados usando código C# ou VB .NET. Isso permite um fácil refatoramento, melhora a legibilidade e o código fica mais conciso.

Apenas para comparar, veja abaixo um exemplo de um arquivo de mapeamento .hbm gerado e sua contrapartida usando o Fluent NHibernate:

(fonte: https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started)

Arquivo XML .hbm:

<?xml version="1.0" encoding="utf-8" ?>  
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  
  namespace="QuickStart" assembly="QuickStart">  
  <class name="Cat" table="Cat">  
    <id name="Id">  
      <generator class="identity" />  
    </id>  
    <property name="Name">  
      <column name="Name" length="16" not-null="true" />  
    </property>  
    <property name="Sex" />  
    <many-to-one name="Mate" />  
    <bag name="Kittens">  
      <key column="mother_id" />  
      <one-to-many class="Cat" />  
    </bag>  
  </class>  
</hibernate-mapping>

Código Fluent NHibernate equivalente:

public class CatMap : ClassMap<Cat>
{
  public CatMap()
  {
    Id(x => x.Id);
    Map(x => x.Name)
      .Length(16)
      .Not.Nullable();
    Map(x => x.Sex);
    References(x => x.Mate);
    HasMany(x => x.Kittens);
  }
}

O Fluent NHibernate pode ser baixado neste link, ou se preferir via Nuget.

Neste artigo, eu vou criar um projeto ASP .NET MVC  (linguagem C#) e usar o NHibernate e o Fluent NHibernate para definir as classes POCO do mapeamento via código para criar as tabelas em tempo de execução no SQL Server 2012.

Recursos usados:

Objetivos:

  • Usar os recursos do NHibernate e Fluent NHibernate e realizar o CRUD em uma aplicação ASP .NET MVC

Aprendizado:

  • Realizar o CRUD em uma aplicação ASP .NET MVC usando a linguagem C#
  • Criar um banco de dados SQL Server 2012 Express
  • Criar as entidades que fazem partem do modelo
  • Realizar o mapeamento ORM usando o Fluent NHibernate
  • Criar a classe NHibernateHelper e definir a SessionFactory
  • Criar o controlador, definir os métodos e criar as views para realizar o CRUD

Criando o projeto no VS Community

Abra o VS Community 2015 e clique em New Project. A seguir, selecione Visual C# -> Web -> ASP .NET Web Application.

Informe o nome CRUD_FluentNHibernate e clique no botão OK:

mvc_crudnhb11

Selecione o template Empty e marque a opção MVC, sem autenticação, conforme figura a seguir:

mvc_crudnhb12

Vamos agora incluir a referência no projeto ao NHibernate e ao Fluent NHibernate via Nuget. Para isso, no menu Tools, clique em Nuget Manager Package e, a seguir, em Manage Nuget Packages for Solution.

Localize o pacote do FluentNhibernate e instale-o no projeto:

mvc_crudnhb13

Definindo a fonte e o modelo de dados

Para este exemplo, eu vou usar o banco de dados chamado Cadastro.mdf e a tabela Alunos que possui a seguinte estrutura:

Estrutura da Tabela Aluno:

mvc_crudnhb14

Script SQL para gerar a tabela Alunos:

USE [Cadastro]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Alunos](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Nome] [nvarchar](50) NOT NULL,
	[Email] [nvarchar](100) NOT NULL,
	[Curso] [nvarchar](50) NULL,
	[Sexo] [nvarchar](50) NULL,
 CONSTRAINT [PK_Alunos] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

Aproveite para incluir alguns dados na tabela alunos para efeito de testes.

Agora, vamos criar na pasta Models do projeto a nossa classe de domínio que é uma classe POCO que representa um aluno.

Clique com o botão direito sobre a pasta Models e, a seguir, em Add Class, informe nome Aluno e digite o código abaixo para a classe Aluno:

public class Aluno
 {
            public virtual int Id { get; set; }
            public virtual string Nome { get; set; }
            public virtual string Email { get; set; }
            public virtual string Curso { get; set; }
            public virtual string Sexo { get; set; }
 }

Vamos criar agora a nossa classe de mapeamento usando o FluentNHibernate que mapeará a nossa classe de modelo(Aluno) para a tabelaAlunos do banco dados.

Clique com o botão direito sobre a pasta Models e, a seguir, em Add Class, informe nome AlunoMap e digite o código abaixo para a classe:

using FluentNHibernate.Mapping;
namespace Crud_FluentNHibernate.Models
{
    class AlunoMap : ClassMap<Aluno>
    {
        public AlunoMap()
        {
            Id(x => x.Id);
            Map(x => x.Nome);
            Map(x => x.Email);
            Map(x => x.Curso);
            Map(x => x.Sexo);
            Table("Alunos");
        }
    }
}

Neste código mapeamos as propriedades definidas na classe Aluno para os campos da tabela Alunos definida na propriedade Table do Fluente NHibernate.

Usamos aqui as expressões lambdas que são funções e podem conter expressões e declarações que são usadas para criar delegates e árvores de expressões, onde o tipo das variáveis não precisam ser declarados, visto que elas usam métodos anônimos.

Para saber mais sobre expressões lambdas, veja o meu artigo: .NET – Expressões Lambdas

Vamos, agora, criar a classe NHibernateHelper que irá realizar a conexão com o banco de dados SQL Server.

Clique com o botão direito sobre a pasta Models e, a seguir, em Add Class, informe nome NHibernateHelper e digite o código abaixo para a classe:

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
namespace Crud_FluentNHibernate.Models
{
    public class NHibernateHelper
    {
        public static ISession OpenSession()
        {
            ISessionFactory sessionFactory = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2012
                  .ConnectionString(@"Data Source=(localDB)\v11.0;Initial Catalog=Cadastro;Integrated Security=True")
                              .ShowSql()
                )
               .Mappings(m =>
                          m.FluentMappings
                              .AddFromAssemblyOf<Aluno>())
                .ExposeConfiguration(cfg => new SchemaExport(cfg)
                                                .Create(false, false))
                .BuildSessionFactory();
            return sessionFactory.OpenSession();
        }
    }
}

No código acima, criamos o método OpenSession, que será responsável por disponibilizar uma session que representa o nosso contexto. Nesta classe, temos a string de conexão com o banco de dados Cadastro.mdf do SQL Server 2012.

Na segunda parte do artigo, vamos definir o controlador e os métodos para realizar o CRUD.