Fluent NHibernate have a nice AutoMapping feature, where you can set some conventions to represent how your entities are mapped to the database. It allows you to make projects with NHibernate easily without the hard work with mapping files.
Today I was trying to make a little tweak on only one of my entities which behaves different from the others. Almost every entities in my domain have its Id property generated by Identity. The one I wanted to tweak has its Id property assigned instead of generated. So I did some dig around looking for a way to do this. It was pretty hard and time consuming to find a solution, but I finnaly found something useful. That’s what I’ll show now:
Suppose we have a class Visitor and Employee:
public class Visitor
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public class Employee
{
public string Id { get; set; }
public string Name { get; set; }
public Department Department { get; set; }
}
Our employee Id is generated by identity while Visitor is assigned.
Here’s the automapping configuration with the conventions:
public AutoPersistenceModel Generate()
{
AutoPersistenceModel mappings = AutoPersistenceModel
.MapEntitiesFromAssemblyOf<Visitor>()
.Where(GetAutoMappingFilter)
.ConventionDiscovery.Setup(GetConventions())
.WithSetup(GetSetup())
.UseOverridesFromAssemblyOf<AutoPersistenceModelGenerator>();
return mappings;
}
private Action<IConventionFinder> GetConventions()
{
return c =>
{
c.Add<PrimaryKeyConvention>();
};
}
public class PrimaryKeyConvention : IIdConvention
{
public bool Accept(IIdentityPart id)
{
return true;
}
public void Apply(IIdentityPart id)
{
id.ColumnName("Id")
.WithUnsavedValue(0)
.GeneratedBy.Identity(); //Here we are saying to generate our entities Id by identity.
}
}
This way both Visitor and Entity will have its id generated by identity based on our primary key convention. To make only the Visitor entity assigned instead of generated we can use the .ForTypesThatDeriveFrom<T>(Action<AutoMap<T>>) method:
public AutoPersistenceModel Generate()
{
AutoPersistenceModel mappings = AutoPersistenceModel
.MapEntitiesFromAssemblyOf<Visitor>()
.Where(GetAutoMappingFilter)
.ConventionDiscovery.Setup(GetConventions())
.WithSetup(GetSetup())
.UseOverridesFromAssemblyOf<AutoPersistenceModelGenerator>()
.ForTypesThatDeriveFrom<Visitor>(autoMap => autoMap.Id(v => v.Id).GeneratedBy.Assigned()); //This will make visitor have its Id assigned.
return mappings;
}
.ForTypesThatDeriveFrom we can tweak the behavior of any entity to be different from conventions.
Posted by neotk