Try fast search NHibernate

29 June 2010

Alt.Net Hispano Vale!!

Bueno, que Alt.Net Hispano, con todo su aporte, Vale mucho ya lo saben.

La novedad es que el sabado pasado, para llenar un sabado sin VAN, hicimos un Alt.Net café con un poco de ejercicio de TDD al estilo Maulo (que vendría a ser como me sale a mi).

El resultado es que nació un nuevo framework de validación que se espera nos sirva para involucrar más gente al mundo OpenSource y, tal vez, para generar otros ejemplos de varias herramientas y tecnicas que el mundo Alt.Net quiere mucho.

El video del encuentro, como siempre, lo pueden ver en el wiki de las reuniones .

El sitio del nuevo framework es http://vale.codeplex.com/ y su nacimiento fue grabado en un screencast:

04 June 2010

NHibernate SVN local mirror

In my SkyDrive I have uploaded the SVN-mirror with full history of NHibernate trunk.
It is updated to 4985 revision. You can use it as you need.
To update it the command example is:
D:\svnmirrors>svnsync sync file:///d:/svnmirrors/NHibernateMirror

When you have an updated revision, you can use it to create your own fork where you need.
To convert it to Mercurial what you need is only the last steps explained in this blog post.

To download it click below.

01 June 2010

Duck Typing with NHibernate Reloaded

Around two years ago you read this post. One year ago you read this other post. Today we have DLR!!!

The mapping

Again the same mapping:
  1. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  2.     
  3.     <class entity-name="ProductLine">
  4.         <id name="Id" type="int">
  5.             <generator class="hilo"/>
  6.         </id>
  7.         <property name="Description" not-null="true" length="200" type="string"/>
  8.  
  9.         <bag name="Models" cascade="all" inverse="true">
  10.             <key column="productId"/>
  11.             <one-to-many class="Model"/>
  12.         </bag>
  13.  
  14.     </class>
  15.  
  16.     <class entity-name="Model">
  17.         <id name="Id" type="int">
  18.             <generator class="hilo"/>
  19.         </id>
  20.  
  21.         <property name="Name" not-null="true" length="25" type="string"/>
  22.         <property name="Description" not-null="true" length="200" type="string"/>
  23.         <many-to-one name="ProductLine"
  24.                      column="productId"
  25.                      not-null="true"
  26.                      class="ProductLine"/>
  27.     </class>
  28.  
  29. </hibernate-mapping>

Saving Ducks

Instead anonymous objects this time I’ll use a DynamicEntity.
  1. using (ISession s = sessions.OpenSession())
  2. using (ITransaction t = s.BeginTransaction())
  3. {
  4.     dynamic line = new DynamicEntity();
  5.     line.Description = "High quality cars";
  6.     line.Models = new ArrayList();
  7.     line.Pizza = "calda";
  8.  
  9.     dynamic ferrari = new DynamicEntity();
  10.     ferrari.ProductLine = line;
  11.     ferrari.Name = "Dino";
  12.     ferrari.Description = "Ferrari Dino";
  13.     ferrari.Fuel = "Gasoline";
  14.  
  15.     dynamic lamborghini = new DynamicEntity();
  16.     lamborghini.ProductLine = line;
  17.     lamborghini.Name = "Countach";
  18.     lamborghini.Description = "Lamborghini Countach";
  19.     lamborghini.Origin = "Italy";
  20.     line.Models.Add(ferrari);
  21.     line.Models.Add(lamborghini);
  22.  
  23.     savedId = s.Save("ProductLine", (object)line);
  24.     t.Commit();
  25. }

Updating Ducks

  1. dynamic productLine;
  2. using (ISession s = sessions.OpenSession())
  3. using (ITransaction t = s.BeginTransaction())
  4. {
  5.     var entity = s.Get("ProductLine", savedId);
  6.     productLine = new DynamicEntity(entity);
  7.  
  8.     productLine.Description = "Quality cars";
  9.     dynamic newModel = new DynamicEntity();
  10.     newModel.ProductLine = entity;
  11.     newModel.Name = "Locus";
  12.     newModel.Description = "Audi Locus";
  13.  
  14.     productLine.Models.Add(newModel);
  15.  
  16.     t.Commit(); // Persist modification
  17. }
  18.  
  19. // Test over modifications
  20. using (ISession s = sessions.OpenSession())
  21. {
  22.     var entity = s.Get("ProductLine", savedId);
  23.     productLine = new DynamicEntity(entity);
  24.     Assert.AreEqual("Quality cars",productLine.Description);
  25.     Assert.AreEqual(3, productLine.Models.Count);
  26. }

Deleting Ducks

  1. using (ISession s = sessions.OpenSession())
  2. using (ITransaction t = s.BeginTransaction())
  3. {
  4.     // Delete the detached dynamic entity
  5.     s.Delete("ProductLine", productLine);
  6.     t.Commit();
  7. }
  8.  
  9. using (ISession s = sessions.OpenSession())
  10. {
  11.     // check entity deletation with cascade
  12.     s.Get("ProductLine", savedId).Should().Be.Null();
  13.     s.CreateQuery("from Model").List().Count.Should().Be.EqualTo(0);
  14. }

The “Magic”

This time the magic is all in few lines of one class…
  1. public class DynamicEntity : DynamicObject, IDictionary
  2. {
  3.     private readonly Hashtable dictionary = new Hashtable();
  4.  
  5.     public DynamicEntity()
  6.     {
  7.     }
  8.  
  9.     public DynamicEntity(object fromNh)
  10.     {
  11.         dictionary = fromNh as Hashtable;
  12.     }
  13.  
  14.     public override bool TryGetMember(GetMemberBinder binder, out object result)
  15.     {
  16.         string name = binder.Name;
  17.         result = dictionary[name];
  18.         var nestedEntity = result as Hashtable;
  19.         if (nestedEntity != null)
  20.         {
  21.             result = new DynamicEntity(nestedEntity);
  22.         }
  23.         return dictionary.Contains(name);
  24.     }
  25.  
  26.     public override bool TrySetMember(SetMemberBinder binder, object value)
  27.     {
  28.         dictionary[binder.Name] = value;
  29.  
  30.         return true;
  31.     }
  32.  
  33.     #region IDictionary Members
  34.     ...
  35.     #endregion
  36. }
The implementation of the IDictionary is only a forward to the dictionary private field.

Conclusion

If you are working with anemic entities, and especially if you then transforms it to DTO, ask yourself why you should write those classes when you can do the same work with just one implementation.
re-NHibernating… quack quack ;-)