2013-06-04 56 views
3

我被認爲是NHibernate的新手。我希望我的Article實體類有兩個懶惰屬性。其中之一是用戶其他是內容。我的實體和映射像NHibernate Linq Provider渴望獲取懶字符串屬性

<class name="Article" table="TBL_ARTICLE"> 
    <id name="Id" column="ART_ID"> 
     <generator class="native" /> 
    </id> 
    <property name="UserId" column="USR_ID" not-null="true" /> 
    <many-to-one name="User" column="USR_ID" insert="false" update="false" /> 
    <property name="Content" column="ART_CONTENT" not-null="true" lazy="true" /> 
</class> 

public class Article 
{ 
    public virtual long Id { get; set; } 
    public virtual long UserId { get; set; } 
    public virtual User User { get; set; } 
    public virtual string Content { get; set; } 
} 

我選擇它喜歡

using(ISession session = sessionFactory.OpenSession()) { 
    return session.Query<Article>() 
        .SingleOrDefault(a => a.Id == id); 
} 

它工作正常。當我嘗試訪問使用塊之外的用戶或內容屬性時,我得到某種延遲加載異常。這是我所期望的。

對於某些情況我喜歡熱切地獲取用戶數據。我選擇它:

using(ISession session = sessionFactory.OpenSession()) { 
    return session.Query<Article>() 
        .Fetch(a => a.User) 
        .SingleOrDefault(a => a.Id == id); 
} 

它仍然正常工作。當我嘗試訪問使用塊之外的User屬性時,我可以擁有它的屬性值,但是當嘗試訪問Content屬性時,我仍然得到某種延遲加載異常,這仍然是我的預期。

當我想取像

using(ISession session = sessionFactory.OpenSession()) { 
    return session.Query<Article>() 
        .Fetch(a => a.Content) 
        .SingleOrDefault(a => a.Id == id); 
} 

內容數據我得到一個異常:

Invalid join: a.Content 
[.SingleOrDefault[Repository.NH.Article](.Fetch[Repository.NH.Article,System.String] 
(NHibernate.Linq.NhQueryable`1[Repository.NH.Article], Quote((a,) => (a.Content)),), 
Quote((a,) => (Equal(a.Id, 1))),)] 

我讀了一些博客文章有關HQL這樣做,但我正在尋找使用LINQ的解決方案供應商。

回答

1

Fetch構造僅適用於映射對象之間關係的屬性,因此屬性映射爲「參考」,「多對一」或「多對多」。

這就是爲什麼它按照預期與User屬性一起工作,但不符合字符串Content屬性的原因。

經過進一步調查,我不認爲你可以實現你想要使用LINQ語法什麼,但它應該使用使用fetch all properties提示等效HQL聲明可能:

session.CreateQuery("from Article fetch all properties") 
+0

有沒有什麼可以提取內容數據的熱切?可能是EF中的一些包含方法。如果沒有,我們可以說懶惰的標量屬性不能使用linq提供程序獲取嗎? –

+0

@MehmetAtaş不是我知道 - 顯然,如果您訪問您的使用語句中的內容屬性它將被加載,但這仍然是加載後,因爲它不會被填充爲您的初始查詢的一部分。你爲什麼要這個特定的屬性後裝? – CSL

+0

@MehmetAtaşEF包含方法的功能與nHibernate中的Fetch相同 – CSL

0

你一般使用懶引用類型,例如導致在SQL中加入的東西。由於內容是一個字符串,並且與對象圖的層次完全相同,因此您所做的事情沒有多大意義。當你試圖在你的nhibernate會話之外引用對象字符串屬性時發生了什麼,它引發了一個錯誤。另一方面,你不能獲取非引用類型,因此你的問題。但是,你可以做一些有點不同的事情。如果您需要使用Lazy內容拉出對象,請在您的nhibernate會話範圍內使用Query,如果您希望內容被急切拉出,請使用_session.Get<Article>(id); Get將從數據庫中加載完整的對象圖。

+0

使用'.Get

(id)'不會急於拉動懶惰屬性。他們將被要求在一個單獨的訪問查詢。 – Nathan

0

正如其他人已經解釋的,引用和懶惰標量屬性的行爲有所不同,並且LINQ Fetch方法僅適用於前者。

有你的問題,有三種可能的解決方案:

  • 使用HQL,而不是LINQ,爲CSL建議,當你需要急切地加載延遲屬性。
  • 請勿使用懶惰屬性,並在顯示列表時使用投影,而不是提取完整實體。
  • 修復您的實際問題,這是您的會話範圍。在您仍在使用這些實體時,它應該始終可用。