Fluent NHibernate - переопределить имена таблиц из сопоставления

Я использую Fluent NHibernate для сопоставления моих моделей NHibernate.

Теперь я столкнулся с проблемой, что я хочу поставить перед всеми своими таблицами знак подчеркивания в некоторых случаях. Так что я не могу просто изменить определение Table(...) в моем отображении, я должен делать это извне.

Что у меня есть на данный момент:

Модель:

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

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

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

Где-то в моем контроллере:

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

Это всегда выводит "foo_table", а не "_foo_table".

Когда я комментирую определение Table(...), оно работает как шарм ... Но мне нужно установить Table(...) в сопоставлении.


person Jan P.    schedule 11.10.2013    source источник
comment
Возможно, вам придется сделать это явно для каждой таблицы, если вы хотите сделать это только для некоторых таблиц. Если вы используете автоматическое сопоставление, вам также необходимо выполнить сопоставление вручную. См. Здесь раздел «Смешанные сопоставления с плавным доступом и автоматические сопоставления»: github.com/jagregory/ fluent-nhibernate / вики /   -  person John S.    schedule 11.10.2013
comment
Это далеко не отличная идея, но может ли это быть вариант иметь ваши сопоставления, такие как Table (UtilityClass.GetTableName (foo_table)), где UtilityClass будет полагаться на некоторую переменную конфигурации / контекста для префикса tableName с подчеркиванием?   -  person jbl    schedule 11.10.2013
comment
Действительно старый вопрос ... Вы нашли решение (3 года назад: D)?   -  person madflow    schedule 22.08.2014


Ответы (3)


Пока вы определяете

Table("foo_table");

вам нужно будет обновить все эти места и добавить к ним свой префикс. Было бы лучше использовать постоянное значение, определенное где-то, что если вам придется его снова изменить, все это будет в одном месте ...

public const string TABLE_PREFIX = "_";

а затем используйте это

Table(TABLE_PREFIX + "foo_table");

для упрощения рефакторинга просто найдите Table(" и замените его на Table(TABLE_PREFIX + " во всех файлах ...

person MichaC    schedule 12.10.2013

Вы можете попробовать использовать следующее соглашение:

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);
        }
    }
}

Затем вам нужно будет построить фабрику сеансов примерно так:

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

Любые изменения в ваших сопоставлениях после создания фабрики сеансов с помощью Fluent NHibernate потребуют, чтобы вы перестроили фабрику сеансов с новыми сопоставлениями таблиц, которые вы хотите.

person Cole W    schedule 14.10.2013

Приведенные выше ответы дали мне ошибку сервера sql из-за "" "вокруг имени таблицы. Они также не включали все типы сопоставлений, такие как подклассы и коллекции.

Вот что сработало для меня:

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);
        }
    }
}

Как упомянул @ [Cole W], вам нужно создать sessionFactory с соблюдением соглашений:

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