Interesting project, maybe we can switch to it from hbm.xml. The advantages are obvious:

  • Easier refactoring
  • Automapping
  • Smaller

... read more on a web site http://fluentnhibernate.org/

Traditional HBM XML mapping

<?xml version="1.0" encoding="utf-8" ?>  
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  
  namespace="QuickStart" assembly="QuickStart">  
  
  <class name="Cat" table="Cat">  
    <id name="Id">  
      <generator class="identity" />  
    </id>  
  
    <property name="Name">  
      <column name="Name" length="16" not-null="true" />  
    </property>  
    <property name="Sex" />  
    <many-to-one name="Mate" />  
    <bag name="Kittens">  
      <key column="mother_id"/>  
        <one-to-many class="Cat"/>  
      </bag>  
  </class>  
</hibernate-mapping>  

Fluent NHibernate equivalent

public class CatMap : ClassMap<Cat>  
{  
  public CatMap()  
  {  
    Id(x => x.Id);  
    Map(x => x.Name)  
      .WithLengthOf(16)  
      .Not.Nullable();  
    Map(x => x.Sex);  
    References(x => x.Mate);  
    HasMany(x => x.Kittens);  
  }  
}  
  • No labels

3 Comments

  1. Unknown User (muurman)

    You can also use a persistenmodel with fluent MNhibernate. Here you specify how you want your entities mapped in a general way. This way you don't have to map every entity seperately. You can specify exclusions and use hbm.xml or a fluent map for other classes.

    Here is an extremely fluent example

    AutoPersistenceModel example

    private static AutoPersistenceModel GetPersistenceModelFromAutoMapping()
    {
    return AutoPersistenceModel.MapEntitiesFromAssemblyOf<Customer>()
    .Where(type =>
    IEntity).IsAssignableFrom(type)
    && type.IsClass
    && \!type.IsAbstract
    && type.Namespace == "CustomerConfiguration")
    
    // defining convention attributes
    .WithConvention(convention =>
    {
    convention.FindIdentity = p => p.Name == "ID";
    convention.GetTableName = type => Inflector.Pluralize(type.Name);
    convention.GetPrimaryKeyNameFromType = type => type.Name + "ID";
    convention.GetForeignKeyNameOfParent = p => p.Name + "ID";
    convention.DefaultStringLength = 50;
    convention.OneToManyConvention = o => o.Cascade.All();
    });
    }
    

    Advantages :
    Simple classes can be mapped automatically

    Refactor / Rename proof

    Convention over configuration

    You can specify exclusions and use hbm.xml or fluent maps where you want.

    'Disadvantages':
    Uses a lot of lambda expressions. Not easy to read when you don't know
    Adds an extra layer of abstraction away from your sql->entity mapping

    http://blog.vuscode.com/malovicn/archive/2009/01/03/fluent-nhibernate-nhibernate-without-configuration-files-automap-magic.aspx

    1. Unknown User (don) AUTHOR

      I think we certainly should try it, but may be not in all situations. The issues can arise with backward compatibility, in this case hbm.xml is more restrictive and will make sure that table name is not changed when entity name is changed. However maybe Reading objects using one version and saving using another will be a solution.

      Where it can be used is to auto-serialize items used as a project data and exposed using IDataProvider. All types returned by data providers can be serialized using fluent by default when no hbm.xml is defined.