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:
- Visual Studio 2015 Community
- Linguagem C#
- NHibernate 4.0
- Fluent NHibernate
- SQL Server 2012 Express
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:
Selecione o template Empty e marque a opção MVC, sem autenticação, conforme figura a seguir:
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:
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:
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.