Lazy loading не работает для отношений "много-к-одному" при сопоставлении с не-ключевым полем, используя свойство-ref

У меня есть устаревшая база данных, которую я сопоставляю с помощью 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>();

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

Ответы

Ответ 1

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

См. также: