Sunday, November 2, 2014

NHibernate - Configuración




Partamos de un dominio sencillo: Autores literarios y sus libros, nuestro dominio sería algo como:


public class Author
{
   public virtual int Id
   { getset; }
   public virtual string FirstName
   { get; set; }

   public virtual string LastName

   { get; set; }

   public virtual IEnumerable<Book> Books

   { getset; }
}

 

public class Book
{
   public virtual int Id
   { getset; }
   public virtual string Title
   { get; set; }

   public virtual string Description
   { get; set; }

   public virtual Author Author

   { getset; }
}

Para asegurar la independencia de nuestro dominio de la tecnología que utilicemos para el acceso a datos, en este caso NHibernate, vamos a crear un nuevo proyecto y añadir la referencia a NHibernate en este nuevo proyecto. Además de la referencia a NHibernate, he añadido la una referencia a FluentNHibernate, para poder configurar mi dominio (prometo volver sobre el uso de Fluent en otro post).
En este momento nuestro proyecto tiene la estructura siguiente:







El siguiente pase es la configuración del mapping de NHibernate, para ello vamos a utilizar Fluent NHibernate. Cada objeto del dominio se mapea en una clase ClassMap de nuestro proyecto de acceso a datos:

 

public class AuthorMap : ClassMap<Author>

{
   public AuthorMap()
   {
      Id(x => x.Id)
               .Column("Id")
               .GeneratedBy.Identity();
      Map(x => x.FirstName).Column("FirstName").Not.Nullable();

      Map(x => x.LastName).Column("LastName").Nullable();
      HasMany(x => x.Books)
                    .KeyColumn("AuthorId")
                    .Inverse()
                    .Cascade.AllDeleteOrphan();
   }
}

 

public class BookMap : ClassMap<Book>

{
   public BookMap()
   {
      Id(x => x.Id)
               .Column("Id")
               .GeneratedBy.Identity();
      Map(x => x.Title).Column("Title").Not.Nullable();

      Map(x => x.Description).Column("Description").Nullable();
      References(x => x.Author).Column("AuthorId");
   }
}

Ya solo queda crear un proyecto de tests para probar nuestra configuracion, el test siguiente prueba el almacenamiento de un autor y su libro asociado


[TestClass]

public class DataTests

{

   private static ISessionFactory _sessionFactory;


    [TestInitialize]
   public void Init()
   {
      _sessionFactory Fluently.Configure()
                                .Database(MsSqlConfiguration.MsSql2012
                                .ConnectionString(x => x.FromConnectionStringWithKey("sample")))
                                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<AuthorMap>())
                                .BuildSessionFactory();
   }

    [TestMethod]
   public void SaveAuthor_Author_AuthorSaved()
   {
      var author new Author()
      {
         FirstName "Orson",
         LastName "Scott Card",
         Books new List<Book>() {
            new Book()
            {
               Description "Ender's Game is a 1985 military science fiction novel",
               Title"Ender's Game"

            }
         }
      };

      using (var session = _sessionFactory.OpenSession())

      using (var transaction = session.BeginTransaction())
      {
         session.SaveOrUpdate(author);
      }
   }
}


  

No comments:

Post a Comment