Quem me conhece sabe como sou fã no NHibernate. Já utilizo há vários anos e já se comprovou como um ORM completo e confiável. Se você não conhece, dê uma lida nestes sites para conhecer:
Mas mesmo gostando do NHibernate, ele tinha se tornado um problema desde o lançamento do .NET Core. Na verdade, ele não era o problema; mas sim a falta dele no ecossistema do .NET Core. A Microsoft lançou em conjunto com o .NET Core o Entity Framework Core, mas como pode ser visto no roadmap do EF, ele ainda tem algumas features faltando para ser considerado um ORM completo.
A esperança era que, em algum momento, o NHibernate fosse portado para o .NET Core. A esperança era pequena porque a dependência por APIs do .NET Framework (full framework) era grande. Nesse vácuo, outros frameworks começaram a se despontar como o Dapper, mas não dá para comparar as features que tínhamos no NHibernate com um micro ORM.
Quando a Microsoft anunciou o .NET Standard 2.0, as esperanças renasceram. A proposta de incorporar uma boa parte das APIs do .NET Framework no .NET Core era muito animadora – até gravamos um podcast sobre isso.
A partir desse anuncio, fiquei monitorando o repositório do NHibernate Core para ver como estava o andamento do trabalho, até surgir a branch NH999 que está ligado ao porte do NH para o .NET Core 2. Fiquei animado e monitorando os PRs do NH até ver que, em agosto, o Nathan Brown fez um PR no qual ele fala que os testes já estão passando no Windows com SQL Server e ele já estava disponibilizando os nugets em um feed público.
Na mesma semana, fui testar e estava funcionando. Vou mostrar para vocês como vocês podem reproduzir esse teste, porque se vocês forem como eu, só vão acreditar vendo.
Mão na massa
Primeira coisa, é necessário configurar no Visual Studio um novo Feed de Nuget. Adicione a URL https://ci.appveyor.com/nuget/nhibernate-core-6cm11v2xdhud como um source de Nuget.
Adicione o pacote NHibernate.Driver.SqlServer. Não se esqueça de pesquisar no feed que você acabou de adicionar. É necessário marcar a opção pré-release:
Depois de instalado, vamos criar a configuração do NHibernate a moda antiga, com os benditos XML (eu costumo fazer mapeamento com o Fluent NHibernate, mas ele ainda não está portado). Para o nosso teste, essa configuração será suficiente. Primeiro, vamos configurar a conexão com um arquivo hibernate.cfg.xml. Esse arquivo deve estar na raiz do projeto e deve ser configurado nas propriedades do arquivo do projeto que o Build Action para None e Copy do output Directory para Copy Aways, o conteúdo do arquivo será o seguinte:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.connection_string">Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=NHTeste;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False</property>
<property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
<mapping assembly="ConsoleApp1"/>
</session-factory>
</hibernate-configuration>
</configuration>
Vamos mapear uma entidade simples para inserir e logo depois ler os dados. A entidade e a tabela estão logo abaixo:
public class City
{
public virtual int Id { get; set; }
public virtual long Population { get; set; }
public virtual string Name { get; set; }
}
[\code]
CREATE TABLE [dbo].[City] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] VARCHAR (255) NULL,
[Population] BIGINT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
O arquivo de mapeamento tem o nome de Mapping.hbm.xml esse arquivo deve estar na raiz do projeto e deve ser configurado nas propriedades do arquivo do projeto que o Build Action para Embeded Resource e Copy do output Directory para Do not copy, o conteúdo do arquivo será o seguinte:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ConsoleApp1" namespace="ConsoleApp1" auto-import="true">
<class name="City">
<id name="Id" type="int" generator="identity"/>
<property name="Name" />
<property name="Population" />
</class>
</hibernate-mapping>
Chegando nesse ponto, basta fazer a conexão para obter a sessão do NHibernate, fiz tudo em um console application bem simples só para demonstrar que ele insere e consegue selecionar valores.
class Program
{
static void Main(string[] args)
{
var configuration = new Configuration();
configuration.Configure();
var SessionFactory = configuration.BuildSessionFactory();
var session = SessionFactory.OpenSession();
Console.Write("Digite o nome da Cidade =");
var name = Console.ReadLine();
Console.Write("Digite a populaçao=");
var population = Console.ReadLine();
var city = new City { Name = name, Population = Convert.ToInt16(population) };
session.SaveOrUpdate(city);
session.Flush();
var cities = session.Query<City>()
.Where(p => p.Population > 1000)
.ToList();
Console.WriteLine(quot;Cidades com mais de 1000 pessoas:");
cities.ForEach(x =>
{
Console.WriteLine(quot;{x.Name} -> {x.Population}");
});
Console.ReadLine();
session.Close();
}
}
Quando você executar o programa, ele irá pedir um nome da cidade depois da população inserir e exibir as cidades que têm mais de 1000.
Como eu disse, o teste é bem simples, mas já dá para ver que o trabalho está seguindo e que logo teremos tudo funcionando.
Isso tudo só foi possível por causa de 2 fatores:
- .NET Standard 2 está cobrindo muito mais APIs que o .NET Framewok já cobria. Com isso, ficou muito mais fácil para a equipe do NHibernate portar para o .NET Core 2.0
- Disponibilidade do Nathan Brown para portar, Thanks Nathan!
O aqui está o código desse artigo.
Recomendo dar uma lida na thread desse Pull Request no GitHub.
Vamos torcer para sair logo! E aí o que acharam da novidade?
***
Este artigo foi produzido em parceria com a Lambda3. Leia outros conteúdos no blog da empresa: blog.lambda3.com.br





