Tutorial: ASP.NET MVC com NHibernate e MySQL – Parte 1- Mapeando com Mapping by Code

Bom, como comecei a trabalhar com o NHibernate recentemente, resolvi escrever um post/tutorial básico aqui. Neste tutorial iremos utilizar:

Preparando a solução

Primeiramente, vamos criar uma solução em branco chama mvc-nhibernate:

mvc-nhibernate

Agora vamos adicionar dois projetos, sendo um projeto web – asp.net mvc 4 chamado mvc-app e um class library chamado test-app:

projeto

Agora nós devemos adicionar as referências necessárias para o projeto. Abra o Package Manager Console (Em Tools -> Library Package Manager -> Package Manager Console e digite:

Install-Package NHibernate
Install-Package MySql.Data
Install-Package MySql.Data.Entities
Install-Package MySql.Web

Com o projeto mvc-app selecionado

nuget

E com o projeto test-app selecionado, digitamos:

Install-Package NHibernate
Install-Package NUnit

Criando o modelo

Agora vamos criar o nosso modelo! Neste exemplo, criaremos um cadastro de usuário básico, contendo as seguintes classes:

  • User
  • Adress
  • Country
  • State
  • City
    public class User
    {
        public virtual Guid Id { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string Nick { get; set; }
        public virtual string Email { get; set; }
        public virtual Adress Adress { get; set; }

        public User()
        {

        }

        public virtual string GetFullName()
        {
            return string.Format("{0} {1}", FirstName, LastName);
        }

        public virtual string GetFullNameWithNick()
        {
            return string.Format("{0}{1}{2}", FirstName,
                string.IsNullOrEmpty(Nick) ? " " : " '" + Nick + "' "
                , LastName);
        }
    }

    public class Adress
    {
        public virtual Guid Id { get; set; }
        public virtual string Street { get; set; }
        public virtual string Number { get; set; }
        public virtual string ZipCode { get; set; }
        public virtual City City { get; set; }
        public virtual State State { get; set; }
        public virtual Country Country { get; set; }

        public Adress()
        {
            City = new City();
            State = new State();
            Country = new Country();
        }
    }

    public class City
    {
        public virtual long Id { get; set; }
        public virtual string Name { get; set; }
        public virtual State State { get; set; }

        public City()
        {
        }
    }

    public class State
    {
        public virtual long Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string UF { get; set; }
        public virtual Country Country { get; set; }

        public State()
        {
        }
    }

    public class Country
    {
        public virtual string Iso { get; set; }
        public virtual string Iso3 { get; set; }
        public virtual string Name { get; set; }

        public Country()
        {
        }
    }

Bem, com o nosso modelo em mãos, já podemos começar a criar alguns testes (Na verdade, , o ideal seria criar os testes antes, mas acredito que fica mais fácil para acompanhar escrevendo os testes depois!)

Crie uma pasta no projeto de testes chamada Model e crie uma classe chamada UserTest (Não esqueça de adicionar a referência do projeto mvc-app no projeto test-app)

    [TestFixture]
    class UserTest
    {
        private User user;

        [SetUp]
        public void CreateSchema()
        {
            user = new User
            {
                FirstName = "Rafael",
                LastName = "de Oliveira Marques",
                Nick = "ceb10n",
                Email = "rafaelomarques@gmail.com"
            };
        }

        [Test]
        public void CanGetFullName()
        {
            Assert.AreEqual("Rafael de Oliveira Marques", user.GetFullName());
        }

        [Test]
        public void CanGetFullNameWithNick()
        {
            Assert.AreEqual("Rafael 'ceb10n' de Oliveira Marques", user.GetFullNameWithNick());
        }

        [Test]
        public void CanGetFullNameWithNickNull()
        {
            user.Nick = null;
            Assert.AreEqual("Rafael de Oliveira Marques", user.GetFullNameWithNick());
        }

    }

Para rodar os testes, eu gosto de utilizar o Test Driven .Net, mas fique a vontade para rodá-los da maneira que achar melhor.

 

Mapeando o nosso modelo com Mapping by Code

Primeiramente, vamos criar o arquivo de configuração do nhibernate. No pasta root de nossa app, vamos criar um xml chamado: hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory name="NHibernate.Test">
    <property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="connection.connection_string">Server=localhost;Database=mvcapp;User ID=root;Password=</property>
    <property name="dialect">NHibernate.Dialect.MySQLDialect</property>
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>

Existem outras formas de se fazer, porém, para a nossa app conseguir acessar o nosso arquivo de configuração do NHibernate, nós iremos definir nas propriedades do arquivo: Copy to Output Directory -> Copy Always

Bom, chegou a hora de mapearmos o nosso modelo, que é basicamente um User que possui um Adress. Um Adress que possui uma City, State e Country

    public class UserMap : ClassMapping<User>
    {
        public UserMap()
        {
            Id(x => x.Id, m => m.Generator(Generators.GuidComb));
            
            ManyToOne(x => x.Adress, m =>
            {
                m.Cascade(Cascade.All);
                m.Column("adressId");
                m.Class(typeof(Adress));
            });

            Property(x => x.Email, m => {
                m.NotNullable(true);
                m.Unique(true);
                m.UniqueKey("Email");
            });

            Property(x => x.FirstName, m => m.NotNullable(true));
            Property(x => x.LastName, m => m.NotNullable(true));
            Property(x => x.Nick);
            
        }
    }

    public class AdressMap : ClassMapping<Adress>
    {
        public AdressMap()
        {
            Id(x => x.Id, m => m.Generator(Generators.GuidComb));
            Property(x => x.Street);
            Property(x => x.Number);
            Property(x => x.ZipCode);
            ManyToOne(x => x.City, m =>
            {
                m.Cascade(Cascade.None);
                m.Class(typeof(City));
            });
            ManyToOne(x => x.State, m =>
            {
                m.Cascade(Cascade.None);
                m.Class(typeof(State));
            });
            ManyToOne(x => x.Country, m =>
            {
                m.Cascade(Cascade.None);
                m.Class(typeof(Country));
            });
        }
    }

    public class CityMap : ClassMapping<City>
    {
        public CityMap()
        {
            Id(x => x.Id);
            ManyToOne(x => x.State, m =>
            {
                m.Cascade(Cascade.All);
                m.Column("stateId");
            });
            Property(x => x.Name);
        }
    }

    
    public class StateMap : ClassMapping<State>
    {
        public StateMap()
        {
            Id(x => x.Id);
            Property(x => x.Name);
            Property(x => x.UF);
            ManyToOne(x => x.Country, m =>
            {
                m.Cascade(Cascade.All);
                m.Column("countryId");
            });
        }
    }


    public class CountryMap : ClassMapping<Country>
    {
        public CountryMap()
        {
            Id(x => x.Iso, m => m.Column("Iso"));
            Property(x => x.Name);
            Property(x => x.Iso3);
        }
    }

Agora vamos criar uma pasta chamada Dao, onde criaremos uma classe chamada NHibernateHelper e os nossos DAO’s para realizar operações básicas, como salvar, dar update, etc em nossas entidades.

    public static class NHibernateHelper
    {
        private static ISessionFactory sessionFactory;
        private static Configuration configuration;
        private static HbmMapping mapping;

        public static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }

        public static ISessionFactory SessionFactory
        {
            get
            {
                if (sessionFactory == null)
                    sessionFactory = Configuration.BuildSessionFactory();
                
                return sessionFactory;
            }
        }

        public static Configuration Configuration
        {
            get
            {
                if (configuration == null)
                    configuration = CreateConfiguration();
                
                return configuration;
            }
        }

        public static HbmMapping Mapping
        {
            get
            {
                if (mapping == null)
                    mapping = CreateMapping();
                
                return mapping;
            }
        }

        private static Configuration CreateConfiguration()
        {
            var configuration = new Configuration();
            configuration.Configure();
            configuration.AddDeserializedMapping(Mapping, null);

            return configuration;
        }

        private static HbmMapping CreateMapping()
        {
            var mapper = new ModelMapper();
            mapper.AddMappings(new List<System.Type> { typeof(UserMap) });
            mapper.AddMappings(new List<System.Type> { typeof(AdressMap) });
            mapper.AddMappings(new List<System.Type> { typeof(CityMap) });
            mapper.AddMappings(new List<System.Type> { typeof(StateMap) });
            mapper.AddMappings(new List<System.Type> { typeof(CountryMap) });

            return mapper.CompileMappingForAllExplicitlyAddedEntities();
        }
    }

Feito isso, podemos criar mais alguns testes! Vamos criar uma pasta chamada Dao em nosso projeto de testes e adicionar uma classe chamada NHibernateHelperTest

    [TestFixture]
    class NHibernateHelperTest
    {

        [Test]
        public void CanGenerateSchema()
        {
            var schema = new SchemaUpdate(NHibernateHelper.Configuration);
            schema.Execute(Console.WriteLine, true);
        }

        [Test]
        public void CanOpenSession()
        {
            ISession session = NHibernateHelper.OpenSession();
            Assert.IsNotNull(session);
        }

        [Test]
        public void CanGetConfiguration()
        {
            Assert.IsNotNull(NHibernateHelper.Configuration);
        }
    }

Bom, por hoje é só! Em breve eu publicarei a continuação deste post mostrando como criar os Daos e finalmente trabalhando na View.

Abraço 😉

Anúncios

5 comentários sobre “Tutorial: ASP.NET MVC com NHibernate e MySQL – Parte 1- Mapeando com Mapping by Code

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s