2009-10-29 66 views
9

我在當前項目中有一個奇怪的問題。延遲加載查詢不起作用。當我查詢列表時,nhibernate會分別提取所有關聯。NHibernate通過session.Load()創建代理,但不通過Linq或Criteria API

我提取了它的小部分,並將其放入單獨的解決方案。基本上我現在得到的是帳戶表和帳戶同步表。兩者都有一個ID和一個URL,而ID只是一個db-guid。

我的類別是:

public class HippoAccount 
{ 
    public virtual Guid Id { get; set; } 
    public virtual string Url { get; set; } 
    public virtual HippoAccountSync Sync { get; set; } 
} 

public class HippoAccountSync 
{ 
    public virtual Guid Id { get; set; } 

    public virtual string Url { get; set; } 
    public virtual HippoAccount Account { get; set; } 
} 

當我現在加載對象通過它的GUID:

var account = session.Load<HippoAccount>(accountId); 
Console.WriteLine(NHibernateUtil.IsPropertyInitialized(account, "Sync")) 

...返回false和賬戶本身就是一個代理。

但通過標準API時加載列表:

var account = (HippoAccount)session 
    .CreateCriteria(typeof (HippoAccount)) 
    .Add(Restrictions.Eq("Id", accountId)) 
    .List()[0]; 

...財產Sync被初始化(燒成第二選擇查詢),並且返回的對象不是代理。

這是默認行爲嗎?我錯了什麼?

的映射是:

<class name="HippoAccount" table="AllAccounts"> 
    <id name="Id" type="guid"> 
    <generator class="guid"/> 
    </id> 
    <property name="Url" /> 

    <many-to-one 
      class="HippoAccountSync" 
      name="Sync" 
      not-found="ignore" 
      property-ref="Url"> 
    <column name="url" /> 
    </many-to-one> 
</class> 

<class name="HippoAccountSync" 
     mutable="false" 
     table="Accounts"> 

    <id name="Id" type="guid"> 
    <generator class="guid"/> 
    </id> 

    <property name="Url"> 
    <column name="serviceUri" /> 
    </property> 

    <many-to-one class="HippoAccount" 
       name="Account" 
       property-ref="Url" 
       not-found="ignore"> 

    <column name="serviceUri" /> 
    </many-to-one> 

</class> 
+0

不知道這是否是完全相關的,但也有問題,與未找到= 「忽略」: http://nhjira.koah.net/browse/NH-1001 http://guildsocial.web703 .discountasp.net/dasblogce/CommentView,guid,ba00b19d-bd60-442b-b2e7-935277a9f1eb.aspx – 2009-10-29 18:11:49

+0

你說得對。另一個問題是property-ref - 它也會禁用延遲加載。 http://maonet.wordpress.com/2007/12/05/lazy-load-conflicts-with-property-ref-in-many-to-one-mapping/ – 2009-10-30 12:01:42

回答

10

相當一些調查研究後,我找到了答案。答案,因爲有很多事情可以防止在NHibernate中延遲加載。

  1. 查詢與session.Load:當通過session.Load()獲取一個項目你會得到一個代理。但只要你訪問任何屬性,讓我們說Url,該對象被提取,包括所有它不支持延遲加載的關聯。

  2. property-ref:延遲加載僅適用於對象ID。當通過目標實體中的不同列解決屬性關聯時,NH會熱切地獲取它。 不,這是不可能的,它只是沒有實現:Bug

  3. 未找到=「忽略」允許無效外鍵,也就是說,如果引用的實體沒有找到NH將用null初始化屬性。 NH不會攔截用於延遲加載的屬性訪問,而是指定對象代理。與not-found="ignore"它不能決定該屬性是否應該設置爲null或給定的,可能無效的外鍵的代理。 這可能可以通過攔截屬性訪問來解決。

  4. 當禁用not-found="ignore"property-ref架構出口會產生強制循環引用約束。不好!正確的映射將是一個約束的一對一關係,其中HippoAccountSync的密鑰必須具有生成器foreign

資源

+0

使用session.Load(),您可以,當然,可以安全地訪問代理的Id屬性,而不必訪問數據庫,因爲您已將代理ID設置爲開頭。 – Jay 2010-09-14 14:13:39

+0

鏈接到property-ref bug不再存在,404錯誤。有關這一進展的任何想法? – shanabus 2011-04-25 21:38:12