views:

376

answers:

1

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.

+1  A: 

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.

Steven Lyons
What I mean is that I have Company inheriting from ReferenceEntity and Port inheriting from ReferenceEntity. I want the unique constraint to apply seperately to these classes. I dont mind if there is a Company with the same name as a Port, so long as all ports have unique names and all companies have unique names. Does that change your answer at all?
Alex
@Alex, yes it will work as you want.
Steven Lyons

related questions