R – Specify a Fluent NHibernate automapping to add a unique constraint to all entities

fluent-nhibernate

My automapping:

 return Fluently.Configure()
                .Database(config)
                .Mappings(m =>
                          m.AutoMappings.Add(
                              AutoMap.AssemblyOf<Company>()
                                  .Where(
                                  t => t.Namespace == "DAL.DomainModel" && t.IsClass)
                                  .IgnoreBase<ReferenceEntity>()))
                .BuildSessionFactory();

So ReferenceEntity is an abstract class containing a string Name, and all my reference entities inherit from this class. I'd like to modify my automapping to add a unique constraint to the Name field for all entities that inherit from ReferenceEntity.

I've gathered it has something to do with .Setup but I'm a bit lost on how to proceed.

note: I'm using the Fluent NHibernate v1.0 RTM so conventions will be with the new style if that is relavent to my goal.

Best Answer

If all your entities inherit from ReferenceEntity, wouldn't you want to create the unique constraint for the Name property on all the entities that are mapped?

But if you want to filter by entity base class, you can do it. Use a convention to add the unique constraint to your mappings:

public class NameConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        // Check the entity base class type
        if (instance.EntityType.BaseType.Name == "ReferenceEntity")
        {
            // Only add constraint to the .Name property
            if (instance.Name == "Name")
            {
                instance.Unique();
            }
        }
    }
}

To get the convention (and all other conventions in the assembly) picked up by FNH, just add this line the AutoMap setup you have above:

.Conventions.AddFromAssemblyOf<NameConvention>()

Alex,

No the answer doesn't change. Here is an example, using the convention above.

public abstract class ReferenceEntity
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
}

public class User : ReferenceEntity
{
    public virtual string Email { get; set; }
}

public class Item : ReferenceEntity
{
    public virtual string Description { get; set; }
}

This creates sql of:

create table Users (
    Id INTEGER not null,
   Email TEXT not null,
   Name TEXT not null unique,
   primary key (Id)
)

create table Items (
    Id INTEGER not null,
   Description TEXT,
   Name TEXT not null unique,
   primary key (Id)
)

As long as these are separate entities, it will create a unique constraint on the .Name property for each entity.

Related Topic