Neste tutorial vou explicar como dar o primeiro passo com o NHibernate. A configuração não é nada trivial e por isso gera bastante dúvidas.
Vou estar usando a versão mais recente do NHibernate até o momento, se você quiser usar a mesma versão, utilize este link para fazer o download.
Primero passo, criando a estrutura de projetos
Abra o Visual Studio, crie um projeto Web Application e uma Class Library na mesma solução. Vai ficar assim:

Obs.: Eu tenho o costume de deletar a pasta App_Data e a classe Class1 porque não vou utilizar.
Segundo passo, criando o arquivo de configuração
Dentro do projeto Class Library, crie um xml e chame-o de hibernate.cfg.xml. Atenção, é hibernate e não nhibernate!
Dentro deste arquivo ficam as configurações do banco de dados que iremos usar. Aqui será informado qual o provider (sqlserver, mysql, oracle etc), qual a string de conexão, dialeto etc.
Estou usando MSSQL Server e meu arquivo de configuração ficou assim:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="NHibernate">
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Server=(local);initial catalog=MinhaBase;Integrated Security=SSPI</property>
<property name="show_sql">false</property>
<property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="MercadoVader.NHibernateModule" />
</session-factory>
</hibernate-configuration>
Obs.: A única configuração que muda entre meu arquivo e o seu será a string de conexão. No meu caso estou usando localhost com um banco de dados chamado e usando windows authentication.
Clique com o botão direito no arquivo hibernate.cfg.xml e vá em suas propriedades, na opção Copy to Output Directory escolha o valor Copy Always.
Terceiro passo, banco de dados
Não há muito segredo aqui, apenas crie uma base de dados e rode este script para criar uma tabela de produtos.
CREATE TABLE [dbo].[PRODUTO](
[ID] [int] IDENTITY(1,1) NOT NULL,
[NOME] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[PRECO] [decimal](18, 2) NOT NULL,
[DATA_CADASTRO] [datetime] NOT NULL,
CONSTRAINT [PK_PRODUTO] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
Terceiro passo, banco de dados
Não há muito segredo aqui, apenas crie uma base de dados e rode este script para criar uma tabela de produtos.
CREATE TABLE [dbo].[PRODUTO](
[ID] [int] IDENTITY(1,1) NOT NULL,
[NOME] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[PRECO] [decimal](18, 2) NOT NULL,
[DATA_CADASTRO] [datetime] NOT NULL,
CONSTRAINT [PK_PRODUTO] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
Quarto passo, criando um HttpModule pro NHibernate
Essa parte é mais chata, primeiro de tudo, selecione o projeto Class Library e adicione referência à NHibernate.dll que está na pasta Required_Bin dentro do arquivo zip que foi baixado no início do tutorial. Adicione também uma referência à NHibernate.ByteCode.Castle que também veio no arquivo zip. Por último, adicione referência à System.Web, será necessário para poder criar uma classe que herde da System.Web.IHttpModule.
Crie uma classe chamada NHibernateSessionModule dentro da Class Library e coloque este conteúdo nela:
public class NHibernateSessionModule : IHttpModule
{
public static readonly string KEY = "NHibernateSession";
private static ISession _session;
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
context.EndRequest += new EventHandler(context_EndRequest);
}
private void context_EndRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
ISession session = context.Items[KEY] as ISession;
if (session != null)
{
try
{
session.Flush();
session.Close();
}
catch { }
}
context.Items[KEY] = null;
}
private static ISessionFactory factory = null;
private static ISessionFactory GetFactory()
{
if (factory == null)
{
Configuration config = new Configuration();
if (config == null)
throw new InvalidOperationException("NHibernate configuration is null.");
config.Configure();
factory = config.BuildSessionFactory();
if (factory == null)
throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null.");
}
return factory;
}
public static ISession OpenSession()
{
ISession session;
session = GetFactory().OpenSession();
if (session == null)
throw new InvalidOperationException("Call to factory.OpenSession() returned null.");
return session;
}
public static ISession CurrentSession
{
get
{
if (HttpContext.Current == null)
{
if (_session != null)
{
return _session;
}
else
{
_session = OpenSession();
return _session;
}
}
else
{
HttpContext currentContext = HttpContext.Current;
ISession session = currentContext.Items[KEY] as ISession;
if (session == null)
{
session = OpenSession();
currentContext.Items[KEY] = session;
}
return session;
}
}
}
private void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
context.Items[KEY] = OpenSession();
}
}
Pelo fato de esta classe herdar de IHttpModule, ela será chamada toda vez que um HttpRequest for feito para sua aplicação Web. Esta classe cria uma objeto do tipo Session para cada request e só destroi ele no final.Isso garante que teremos apenas uma Sessão aberta para cada request.
Essa parte não é necessária fazer, mas é considerado uma boa prática trabalhar com apenas uma Sessão ao invés de sair criando várias.
Abra o arquivo web.config e procure pela tag httpModules, dentro desta tag adicione mais um valor, que será referência ao módulo que acabamos de criar. Fica assim:
<httpModules>
<add name="NHibernateSessionModule" type="MercadoVader.NHibernateModule.NHibernateSessionModule, MercadoVader.NHibernateModule"/>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
Quinto passo, o mapeamento
Ufa, quase acabando :)
Dentro da Class Library crie uma classe chamada Produto. Crie também uma pasta chamada Mapping e dentro dela crie o arquivo Produto.hbm.xml.
A classe produto fica assim:
public class Produto
{
public int Id { get; set; }
public string Nome { get; set; }
public DateTime DataCadastro { get; set; }
public decimal Preco { get; set; }
}
O arquivo Produto.hbm.xml fica assim:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MercadoVader.NHibernateModule" assembly="MercadoVader.NHibernateModule">
<class name="Produto" table="PRODUTO">
<id name="Id">
<column name="ID" sql-type="int" not-null="true"/>
<generator class="identity" />
</id>
<property name="Nome" type="String">
<column name="NOME" length="100" not-null="true" />
</property>
<property name="Preco" type="Decimal">
<column name="PRECO" precision="18" scale="2" not-null="true" />
</property>
<property name="DataCadastro" type="DateTime">
<column name="DATA_CADASTRO" not-null="true" />
</property>
</class>
</hibernate-mapping>
O que estamos fazendo aqui é criar uma classe que é espelho da nossa tabela no banco de dados e também criando um arquivo de mapeamento que liga a classe com a tabela, nada muito complexo.
Clique com o botão direito no arquivo Produto.hbm.xml e vá em suas propriedades. Na opção Build Action selecione o valor “Embedded Resource”, isso fará com que o arquivo seja compilado dentro de uma DLL.
Sexto passo, será que funciona funciona?
Para testar, você deve selecionar o projeto Web e adicionar referência ao projeto Class Library e também à NHibernate.dll.
Feito isso, entre no Default.aspx.cs e coloque isso no Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
Produto produto = new Produto();
produto.Nome = "Biscoito Trakinas";
produto.Preco = 1.10M;
produto.DataCadastro = DateTime.Now;
NHibernateSessionModule.CurrentSession.Save(produto);
}
Se tudo der certo, deverá haver um registro salvo no banco de dados agora.
Deu certo? Parabéns, o NHibernate está configurando e funcionando.
Não deu? Faça um comentário descrevendo o erro e verei se consigo ajudar.
Documentação do NHibernate está aqui: https://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/
Utilize a documentação para aprender sobre HQL e como buscar dados do banco de dados.
Conforme eu havia comentado neste post, o site summer of nhibernate é muito bom para aprender.
Se eu escrevi algo errado, por favor, me corrijam, já é meio tarde e o sono já está batendo.
Aqui está o projeto que eu criei para download.
Clique aqui para fazer o download de 'MercadorVader, NH + ASP.NET' (1.09 MB)
Até a próxima!