3

I'm using Fluent NHibernate to map my NHibernate models.

Now i came accros the problem, that I want to prefix all my tables with an underscore in some cases. So i can't just change the Table(...) definition in my mapping, I have to do it from the outside.

What I've got so far:

Model:

class Foo
{
    public virtual int Id { get; set; }
}

class FooMapping : ClassMap<Foo>
{
    Table("foo_table");

    Id(x => x.Id).Column("foo_id");
}

Somewhere in my controller:

/*...*/
if (yourehappyandyouknowit)
{
    Fluently.Configure()
    /*...*/
        .Conventions.Add(Table.Is(x => "_" + x.TableName));
    /*...*/
}

This allways puts out "foo_table" and not "_foo_table".

When I comment out the Table(...) definition, it is working like a charm... But I need to have the Table(...) set within the mapping.

Jan P.
  • 3,261
  • 19
  • 26
  • You may have to do that explicitly for each table if you only want to do that for some tables. If you are using automapping, you'll need to also do manual mapping for this. See the section here called "Mixed fluent mappings and auto mappings": https://github.com/jagregory/fluent-nhibernate/wiki/Fluent-configuration – John S. Oct 11 '13 at 12:32
  • Far from being a great idea, but could it be an option to have your mappings like Table(UtilityClass.GetTableName("foo_table")) where UtilityClass would rely on some configuration/context variable to prefix the tableName with an underscore ? – jbl Oct 11 '13 at 14:55
  • Really old question... Have you found a solution (3 Years ago :D ) ? – madflow Aug 22 '14 at 10:10

3 Answers3

0

As long as you define

Table("foo_table");

you'll have to update all those places and add your prefix to it. Would be best to use a constant value defined somewhere that if you have to change that again, it's all in one place...

public const string TABLE_PREFIX = "_";

and then use it

Table(TABLE_PREFIX + "foo_table");

to easily refactor, simply search for Table(" and replace it with Table(TABLE_PREFIX + " in all files...

MichaC
  • 13,104
  • 2
  • 44
  • 56
0

You can try using the following convention:

using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;

namespace MyDatabaseProject.Conventions
{
    public class UnderscoreTableNameConvention : IClassConvention
    {
        public void Accept(IAcceptanceCriteria<IClassInspector> criteria)
        {

        }
        public void Apply(IClassInstance instance)
        {
            instance.Table("_" + instance.TableName);
        }
    }
}

Then you'll need to build your session factory with something like this:

sessionFactory = Fluently.Configure(normalConfig)
                  .Mappings(m =>
                      m.FluentMappings
                      .AddFromAssemblyOf<OrderMap>()
                      .Conventions.AddFromAssemblyOf<UnderscoreTableNameConvention>())
                      .ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate")
                  .BuildSessionFactory();

Any changes to your mappings after you've built your session factory via Fluent NHibernate will require that you rebuild your session factory with the new table mappings you want.

Cole W
  • 15,123
  • 6
  • 51
  • 85
0

The above answers gave me a sql server error because of "`" around the table name. They also didn't include all type of mappings, such as subclasses and collections.

This is what worked for me:

using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestingNhibernate
{
    public class UnderscoreTableNameConvention : IClassConvention, IJoinedSubclassConvention,  ICollectionConvention
    {
        public readonly string PrependToTableName = "_"; 

        public void Apply(IClassInstance instance)
        {
            instance.Table(GetTableName(instance.EntityType.Name));
        }

        public void Apply(IJoinedSubclassInstance instance)
        {
            instance.Table(GetTableName(instance.EntityType.Name));
        }

        public void Apply(ICollectionInstance instance)
        {
            instance.Table(GetTableName(instance.EntityType.Name));
        }

        private string GetTableName(string originalName)
        {
            return string.Format("`{0}{1}`", PrependToTableName, originalName);
        }
    }
}

Like @[Cole W] mentioned, you need to build the sessionFactory with the conventions:

sessionFactory = Fluently.Configure(normalConfig)
                  .Mappings(m =>
                      m.FluentMappings
                      .AddFromAssemblyOf<OrderMap>()
                      .Conventions.AddFromAssemblyOf<UnderscoreTableNameConvention>())
                      .ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate")
                  .BuildSessionFactory();
Rafi
  • 2,433
  • 1
  • 25
  • 33