Свободный NHibernate: Custom ForeignKeyConvention не работает с явно указанными именами таблиц - PullRequest
0 голосов
/ 13 февраля 2012

РЕДАКТИРОВАТЬ: для толпы tl; dr мой вопрос: как мне получить доступ к сопоставлениям из ForeignKeyConvention, чтобы определить имя таблицы, с которой сопоставляется данный тип?

Длинная версия:

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

В моих таблицах используется соглашение, в котором первичный ключ всегда называется «PK», а внешний ключ - «FK», за которым следует имя таблицы внешнего ключа, например, «FKParent».Например:

CREATE TABLE OrderHeader (
    PK INT IDENTITY(1,1) NOT NULL,
    ... 
)

CREATE TABLE OrderDetail (
    PK INT IDENTITY(1,1) NOT NULL, 
    FKOrderHeader INT NOT NULL,
    ...
)

Чтобы сделать эту работу, я построил пользовательскую ForeignKeyConvention, которая выглядит следующим образом:

public class AmberForeignKeyConvention : ForeignKeyConvention
{
    protected override string GetKeyName( Member member, Type type )
    {
        if ( member == null )
            return "FK" + type.Name;  // many-to-many, one-to-many, join

        return "FK" + member.Name; // many-to-one
    }
}

Это работает до тех пор, пока мои объекты называются так же, какстол.Но это ломается, когда это не так.Например, если я хочу отобразить таблицу OrderDetail на класс с именем Detail, я могу сделать это следующим образом:

public class DetailMap : ClassMap<Detail>
{
    public DetailMap()
    {
        Table( "OrderDetail" );
        Id( o => o.PK );
        References( o => o.Order, "FKOrderHeader" );
        ...
    }
}

Отображение работает для загрузки одной сущности, но когда я пытаюсь запустить любой виддля сложного запроса с объединением это не удается, потому что класс AmberForeignKeyConvention делает неверные предположения о том, как сопоставляются столбцы.То есть предполагается, что внешний ключ должен быть «FK» + type.Name, который в данном случае является Order, поэтому он называет внешний ключ «FKOrder» вместо «FKOrderHeader».

Так, как я сказалвыше: у меня вопрос, как мне получить доступ к сопоставлениям из ForeignKeyConvention, чтобы определить имя сопоставленной таблицы данного типа (и в этом отношении и имена сопоставленных столбцов)?Ответ на этот вопрос , кажется, намекает на правильное направление, но я не понимаю, как участвующие классы работают вместе.Когда я просматриваю документацию, она ужасно редка для классов, которые я искал (например, IdMapping class ).

1 Ответ

1 голос
/ 14 февраля 2012

идея состоит в том, чтобы загрузить сопоставления

public class AmberForeignKeyConvention : ForeignKeyConvention
{
    private static IDictionary<Type, string> tablenames;

    static AmberForeignKeyConvention()
    {
        tablenames = Assembly.GetExecutingAssembly().GetTypes()
            .Where(t => typeof(IMappingProvider).IsAssignableFrom(t))
            .ToDictionary(
                t => t.BaseType.GetGenericArguments()[0], 
                t => ((IMappingProvider)Activator.CreateInstance(t)).GetClassMapping().TableName);
    }

    protected override string GetKeyName( Member member, Type type )
    {
        return "FK" + tablenames[type]; // many-to-one
    }
}
...