2009-03-02 5 views
17

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

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 где каждая учетная запись загружается, даже если учетная запись никогда не ссылается. Почему все учетные записи загружаются, когда много-одно отображается как ленивый прокси?

+0

я получаю один и тот же вопрос, я помню пост somehwere говорил много-к-одному собственности рефов не может быть ленивым загружен , Я просто не могу найти источник. Это было с NH 1.2 – Jafin

ответ

13

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

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

+0

Проблема в NH, похоже, находится в TwoPhaseLoad.cs - она ​​проверяет LoadedState и вызывает IType.ResolveIdentifier для перевода KEYs в Entities или Proxies. Здесь используется IType ManyToOne (PK = false, Uniq = true, eager = false). Он заканчивает вызов ResolveIdentifier (значение, сеанс, владелец) из базы EntityType.cs и проверяет IsReferenceToPrimaryKey (= false) и вызывает LoadByUniqueKey(). У этого в свою очередь есть интересный комментарий «TODO: реализовать кеширование? Прокси»? (УРА). Затем, combo of session.PersistenceContext.GetEntity (новый EntityUniqueKey (.. ключ)) + persister.LoadByUniqueKey (.. key) извлекает объект. – quetzalcoatl