Ленивая загрузка не работает для отношения многие-к-одному при отображении в неключевое поле с помощью свойства-ref - PullRequest
17 голосов
/ 03 марта 2009

У меня есть устаревшая база данных, которую я сопоставляю с помощью NHibernate. Объектами беспокойства являются Учетная запись и список объектов Уведомлений. Объекты выглядят так:

public class Notification
{
    public virtual int Id { get; set; }
    public virtual DateTime BatchDate { get; set; }
    /* other properties */

    public virtual Account Account { get; set; }
}

public class Account 
{
    public virtual int Id { get; set; }
    public virtual string AccountNumber { get; set; }
    /* other properties */ 
}

Файлы сопоставления выглядят следующим образом:

<class name="Account" table="Account" dynamic-update="true">
<id name="Id" column="AccountID">
    <generator class="native" />
</id>
<property name="AccountNumber" length="15" not-null="true" />
    <!-- other properties -->
</class>

<class name="Notification" table="Notification">
    <id name="Id" column="Id">
        <generator class="native" />
    </id>
    <!-- other properties -->
    <many-to-one name="Account" class="Account" property-ref="AccountNumber" lazy="proxy">
        <column name="AcctNum" />
    </many-to-one>

Однако, когда я создаю такие критерии, как

return session.CreateCriteria(typeof(Notification)).List<Notification>();

Я получаю сообщение Select N + 1, в котором загружается каждая учетная запись, даже если на нее никогда не ссылаются Почему все учетные записи загружаются, когда «многие к одному» отображаются как ленивый прокси?

1 Ответ

13 голосов
/ 30 сентября 2010

Проблема вызвана атрибутом property-ref. Ленивая загрузка работает только тогда, когда ссылка many-to-one использует первичный ключ другого объекта, поскольку NHibernate предполагает, что есть ограничение внешнего ключа, обеспечивающее допустимость такого значения. С не-первичным ключом (указанным свойством ref) NHibernate не делает этого предположения и, следовательно, не предполагает, что связанный объект должен существовать. Так как он не хочет создавать прокси для несуществующего объекта (т.е. должен быть нулем вместо прокси), он охотно выбирает удаленный объект. Эта же проблема существует, если указано not-found="ignore", поскольку это указывает на то, что отношение внешнего ключа не применяется и может привести к пустой ссылке.

Смотри также:

...