2009-06-10 22 views
0

更新流利,NHibernate的:區分對象加載hierrachy正確

嗯,我由斯圖爾特查爾斯和詹姆斯·格雷戈裏說,我的模型是足夠怪異開始。很顯然,在類之間的雙向引用同時區分不同類型的關係並沒有完成,顯然是出於很好的理由。

我撕下了模型,使用HasManyToMany在用戶和Fiches之間將其更改爲另一個模型,然後添加了一些編碼的驗證以確保我的用戶無法鏈接到多個Fiche。

所以我的答案猜測這種問題是怎樣的一個警告:「不要做」;)

謝謝兩位抽出時間來回答!


大家

的正確使用功能NHibernate的路徑是一個很難,自從我開始感覺真的很爲難,我想它不會傷害尋求幫助。這是事情。

匪徒

我有以下兩類,菲切和用戶。 Fiche必須擁有用戶所有者,並且可以擁有許多用戶關注者。另一方面,用戶可以選擇鏈接到一個並且只有一個Fiche。 (該EntityUpdateTrace基類包含一個GUID ID和創建/修改時間,爲PreSave /更新前使用)

Public Class Fiche 
    Inherits EntityUpdateTrace(Of Fiche) 

    Private m_Owner As User 
    Public Property Owner() As User 
     ' snip 

    Private m_Followers As IList(Of User) 
    Public Property Followers() As IList(Of User) 
     ' snip 

End Class 

Public Class User 
    Inherits EntityUpdateTrace(Of User) 

    Private m_Fiche As Fiche 
    Public Property Fiche() As Fiche 
     ' snip 

End Class 

然後我有以下映射

Public Class FicheMapping 
Inherits ClassMap(Of Fiche) 
Public Sub New() 
    [Not].LazyLoad() 
    Id(Function(f As Fiche) f.Id).GeneratedBy.GuidComb() 
    References(Of User)(Function(f As Fiche) f.Owner).Not.Nullable() 
    HasMany(Of User)(Function(f As Fiche) f.Followers).Inverse() 
End Sub 
End Class 

Public Class UserMapping 
    Inherits ClassMap(Of User) 
    Public Sub New() 
     [Not].LazyLoad() 
     Id(Function(a As User) a.Id).GeneratedBy.GuidComb() 
     References(Of Fiche)(Function(a As User) a.Fiche).Nullable() 
    End Sub 
End Class 

問題

什麼我該死嗎? :) 雖然看起來似乎很簡單,但我似乎無法使用此模型。

  • Fiche加載所有用戶其相關;聽起來合乎邏輯,我想我應該歧視一個特定的參數,但因爲它會是完全與數據庫相關的東西,我不太喜歡這個想法(我試圖保持這些類在域衛生中作爲練習清潔乾淨)。所以如果Fiche非常重要的Fiche是由Alice創建的,隨後是Bob,當重新加載追隨者時,我發現了Alice和Bob。有沒有辦法區分兩種類型的用戶?

  • 我想用一個列表數據庫,以保持追隨者有序的,但只要我改變映射

    的hasMany(用戶)(功能(F作爲菲切)f.Followers) .AsList()。逆()

以下錯誤彈出:

null index column for collection: Followers

的信息,這個錯誤的量是不是真的壓倒性的,這使我想我採取了錯誤的方式,這種模式,這導致我回到了第一個問題......我到底做錯了什麼?

謝謝大家的閱讀,以及對此的任何洞察!

回答

1

List由於列表的語義而發生錯誤。這很棘手,因爲在默認情況下,行李還被映射到IList,但這是由於在.NET框架中缺少具有「bag」語義的集合類型。在概念上,「袋子」中沒有訂單,因爲物品只是被扔進包裏並以任何順序被移走,並且很容易在包內移動。然而,一個列表是固有的排序和索引(把它看作是一個帶有附加語義的數組,因此每個元素都有唯一的索引值)。你得到的錯誤信息表明NHibernate需要一個存儲每個元素的索引值的列(所以它必須是唯一的,因爲它是一個IList,螞蟻整數值)。由於您似乎沒有索引列,因此您必須以其他方式對其進行排序,可能是在查詢中添加了ORDER BY子句。

至於第一個問題,你可能需要重新思考你是如何處理這個問題的。實際上,您可能可以利用NHibernate filters,但我沒有任何經驗可以說明它是如何工作的。您的Followers集合實際上是所有與Fiche(所有參照FicheUser s)相關的用戶,因此它更像是RelatedUsers。使用存儲庫模式,你可以有一個像FindFollowers(Fiche fiche)這樣的方法來查詢所有RelatedUsers,其中User不等於Owner。由於您希望訂購User,此模式可能會使您受益。喜歡的東西(C#,標準查詢):

session.CreateCriteria(typeof(Fiche)) 
    .CreateCriteria("RelatedUsers", JoinType.InnerJoin) 
     .Add(Restrictions.Not(Restrictions.Eq("Id", fiche.Owner.Id))) 
     .AddOrder(Order.Asc("PropertyNameToOrderBy")) 
     .List<User>(); 
+0

關於第一個問題,我不明白爲什麼列表的索引列應該是映射poco類的責任,我覺得很奇怪... 我不知道我完全理解;從我的立場來看,你所建議的是我應該將追隨者關係從Fiche映射中取出,並用對存儲庫查詢的調用來替換它。但是,您給出的查詢作爲示例使用映射關係(在您的案例中稱爲RelatedUsers);我試過查詢和它抱怨財產... – samy 2009-06-10 16:12:37

+0

它抱怨哪個屬性?錯誤信息是什麼? – 2009-06-10 16:51:38

1

這聽起來像你需要一個多到很多,而不是一個一對多。這樣一個用戶可以被多個引用引用。

至於你的集合的排序,AsList將不會工作,除非你的表中有一個索引列;這是一個包含每個記錄的數值的列,沒有間隙。如果您不想要這種行爲,那麼您需要使用order-by屬性。