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<>));
    }
}
Jason More
  • 6,983
  • 6
  • 43
  • 52
  • 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. – James Gregory Aug 26 '10 at 21:56
  • 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. – Jason More Aug 26 '10 at 22:18
  • As-is, it looks like you're treating Location as another base class, in which case the following might work: mappings.IgnoreBase(); Or are going for something like a table-per-subclass? – David Aug 26 '10 at 22:48
  • 1
    I'm trying to do table-per-subclass. There are many properties in Location that I need to reference – Jason More Aug 27 '10 at 17:12
  • Have you resolved this issue? – Serhiy Feb 12 '11 at 10:05

2 Answers2

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));
    }
}
David
  • 2,038
  • 14
  • 11
  • 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. – Jason More Aug 26 '10 at 21:57
  • Euh, interesting. So are you using an inheritance strategy? - http://jagregory.com/writings/fluent-nhibernate-auto-mapping-and-base-classes/ – David Aug 26 '10 at 22:11
  • Yep. It looks just like the one in the example. Here is a link: http://yfrog.com/1gdhfp – Jason More Aug 26 '10 at 22:27
  • I'd appreciate if you could specify to which assembly `Inflector.Net.Inflector.Pluralize` belongs? – Nano Taboada Sep 01 '11 at 04:56
  • It's an assembly called Inflector.Net. Looks like that's been moving around lately. http://weblogs.asp.net/srkirkland/archive/2011/03/15/inflector-for-net.aspx – David Sep 01 '11 at 22:15
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));

    }
}
Derek Greer
  • 15,454
  • 5
  • 45
  • 52