Отображение ссылок на сопутствующие объекты с помощью fluent-nhibernate - PullRequest
0 голосов
/ 06 августа 2009

У меня есть следующая базовая модель домена для моих учетных записей на сайте MVC:

public class Account
{
    public Account()
    { 
        Details = new AccountDetails( this ); 
        Logon = new LogonDetails(this); 
    }
    public virtual int Id { get; private set; }
    public virtual AccountDetails Details { get; set; }
    public virtual LogonDetails Logon { get; set; }
    ...
}

public class AccountDetails
{
    // Primary Key
    public virtual Account Account { get; set; }
    public virtual DateTime Created { get; set; }
    ...
}

public class LogonDetails
{
    // Primary Key
    public virtual Account Account { get; set; }
    public virtual DateTime? LastLogon { get; set; }
    ...
}

И AccountDetails, и LogonDetails используют отображение, подобное этому:

public class AccountDetailsOverride : IAutoMappingOverride<AccountDetails>
{
    public void Override( AutoMap<AccountDetails> mapping )
    {
        mapping
            .UseCompositeId()
            .WithKeyReference( x => x.Account, "AccountId" );

        mapping.IgnoreProperty( x => x.Account );
    }
}       

Я разделил данные учетной записи и данные для входа в систему на отдельные модели, поскольку мне редко нужна эта информация, тогда как для многих операций и авторизации сайта мне нужны идентификатор пользователя и имя. Я хочу, чтобы свойства Details и Logon загружались только при необходимости. С моими текущими попытками картирования я могу получить одно из двух поведений:

# 1 Создать таблицу и загрузить успешно, не может сохранить

Используя это отображение:

public class AutoOverride : IAutoMappingOverride<Account>
{
    public void Override( AutoMap<Account> mapping )
    {
        mapping.LazyLoad();
        mapping
            .References( x => x.Details )
            .WithColumns( x => x.Account.Id )
            .Cascade.All();
        mapping
            .References( x => x.Logon  )
            .WithColumns( x => x.Account.Id )
            .Cascade.All();
    }
}

Таблицы генерируются как ожидалось. Существующие данные правильно загружаются в модель, но я не могу сохранить. Вместо этого я получаю индекс вне диапазона исключений. Предположительно, потому что Account.Details и Account.Logon пытаются использовать одно и то же поле БД для справки (сам Account.Id).

# 2 Таблица содержит дополнительные поля, не сохраняет должным образом

Используя это отображение:

public class AutoOverride : IAutoMappingOverride<Account>
{
    public void Override( AutoMap<Account> mapping )
    {
        mapping.LazyLoad();
        mapping
            .References( x => x.Details )
            .Cascade.All();
        mapping
            .References( x => x.Logon  )
            .Cascade.All();
    }
}

Я получаю таблицу с отдельным полем для Details_id и Logon_id, но они равны нулю, поскольку значение Details.Account.Id равно нулю, когда учетная запись сохраняется. Таким образом, попытка Session.Get учетной записи приводит к пустым деталям и входу в систему. Если я дважды сохраню учетную запись, таблица обновится правильно, и я смогу ее загрузить.

Помощь ... * * 1023 Должен быть способ отображения этой иерархии, и я упускаю что-то простое. Есть ли способ помочь nhibernate выбрать правильное поле (для решения # 1) или заставить его автоматически обновлять зависимые поля после сохранения (для решения # 2)? Спасибо за любые идеи, которые вы, ребята, можете предоставить.

1 Ответ

0 голосов
/ 06 августа 2009

Если я понимаю вашу модель и желаемое поведение, то у вас есть отношения один к одному между Account и AccountDetails и между Account и LogonDetails. References создает отношения многие-к-одному, так что это может стать вашей проблемой; вместо этого попробуйте HasOne.

Тем не менее, по этой и другим причинам я избегаю личных встреч, если в этом нет крайней необходимости. Может быть больше, чем вы показываете, но стоит ли головной боли и уродливой модели избегать загрузки двух DateTime полей?

Наконец, и это в некоторой степени предположение, поскольку я не проверял эту функциональность. Схема XML схемы NHibernate 2.1 (которую FNH перешла на поддерживаемую версию) определяет атрибут lazy для элементов property. Выпуск 1.0 FNH (должен быть через неделю или две) будет поддерживать установку этого атрибута. Как я уже сказал, я не проверял его, но, похоже, это позволит вам лениво загружать отдельные свойства, что именно то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...