Fluent nHibernate Automapping not creating Plural table name
Asked Answered
C

2

6

I have two tables, Locations and Facilities

They map to two classes,

public Location : Entity
{
   //properties
}

public Facility : Entity
{
    public virtual Location Location { get; set; }
}

Everything works just dandy, until I change facility to this

public Facility : Location
{

}

Now I get an exception from nHibernate saying

NHibernate.ADOException was unhandled by user code
  Message=could not execute query
 InnerException: System.Data.SqlClient.SqlException
       Message=Invalid object name 'Facility'.

For some reason it is not creating the plural name of the table into the sql string.

Thanks for any help!

EDIT

This is my current TableNameConvention

public class TableNameConvention : IClassConvention
{
    public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
    {
        instance.Table(Inflector.Net.Inflector.Pluralize(instance.EntityType.Name));
    }
}

When Facility inherits from Entity, the Facility does run through this method. When it inherits from Location, it does not

Edit 2 Figured I'd post everything... Database diagram

public class AutoPersistenceModelGenerator : IAutoPersistenceModelGenerator
{

    #region IAutoPersistenceModelGenerator Members

    public AutoPersistenceModel Generate()
    {
        var mappings = new AutoPersistenceModel();
        mappings.AddEntityAssembly(typeof(Person).Assembly).Where(GetAutoMappingFilter);
        mappings.Conventions.Setup(GetConventions());
        mappings.Setup(GetSetup());
        mappings.IgnoreBase<Entity>();
        mappings.IgnoreBase(typeof(EntityWithTypedId<>));
        mappings.UseOverridesFromAssemblyOf<AutoPersistenceModelGenerator>();

        return mappings;

    }

    #endregion

    private Action<AutoMappingExpressions> GetSetup()
    {
        return c =>
        {
            c.FindIdentity = type => type.Name == "Id";
        };
    }

    private Action<IConventionFinder> GetConventions()
    {
        return c =>
        {
            c.Add<BHP.DEC.Data.NHibernateMaps.Conventions.ForeignKeyConvention>();
            c.Add<BHP.DEC.Data.NHibernateMaps.Conventions.HasManyConvention>();
            c.Add<BHP.DEC.Data.NHibernateMaps.Conventions.HasManyToManyConvention>();
            c.Add<BHP.DEC.Data.NHibernateMaps.Conventions.ManyToManyTableNameConvention>();
            c.Add<BHP.DEC.Data.NHibernateMaps.Conventions.PrimaryKeyConvention>();
            c.Add<BHP.DEC.Data.NHibernateMaps.Conventions.ReferenceConvention>();
            c.Add<BHP.DEC.Data.NHibernateMaps.Conventions.TableNameConvention>();
        };
    }

    /// <summary>
    /// Provides a filter for only including types which inherit from the IEntityWithTypedId interface.
    /// </summary>

    private bool GetAutoMappingFilter(Type t)
    {
        return t.GetInterfaces().Any(x =>
                                        x.IsGenericType &&
                                        x.GetGenericTypeDefinition() == typeof(IEntityWithTypedId<>));
    }
}
Compromise answered 26/8, 2010 at 21:48 Comment(5)
Fluent NHibernate doesn't do any pluralization of table names, or anything else for that matter. You need to create a convention like David suggested and utilise one of the .Net inflectors out there.Sourdough
The tableNameConvention is in there, but for some reason when I change Facility to inherit from Location, the fluent setup no longer finds it when it scans the assembly.Compromise
As-is, it looks like you're treating Location as another base class, in which case the following might work: mappings.IgnoreBase<Location>(); Or are going for something like a table-per-subclass?Sailcloth
I'm trying to do table-per-subclass. There are many properties in Location that I need to referenceCompromise
Have you resolved this issue?Sigvard
S
9

Have you set a convention?

public class TableNameConvention : IClassConvention
{
    public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
    {
        string typeName = instance.EntityType.Name;

        instance.Table(Inflector.Net.Inflector.Pluralize(typeName));
    }
}
Sailcloth answered 26/8, 2010 at 21:52 Comment(5)
Yeah thats in there. For some reason when I change the Facility to inherit from location Facility does not show up to be added in this table name convention.Compromise
Euh, interesting. So are you using an inheritance strategy? - jagregory.com/writings/…Sailcloth
Yep. It looks just like the one in the example. Here is a link: yfrog.com/1gdhfpCompromise
I'd appreciate if you could specify to which assembly Inflector.Net.Inflector.Pluralize belongs?Lowspirited
It's an assembly called Inflector.Net. Looks like that's been moving around lately. weblogs.asp.net/srkirkland/archive/2011/03/15/…Sailcloth
L
1

This is an old question, but for the sake of others who stumble upon this looking for an answer, you can also create a convention that uses the built-in PluralizationService that comes with EF:

public class TableNameConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        string typeName = instance.EntityType.Name;
        instance.Table(PluralizationService.CreateService(CultureInfo.CurrentCulture).Pluralize(typeName));

    }
}
Langur answered 28/5, 2013 at 17:7 Comment(1)
Interesting mix of nhibernate and EF. We were not allowed to use EF for this project years ago.Compromise

© 2022 - 2024 — McMap. All rights reserved.