2010-06-08 26 views
1

我有一些數據庫表中,看起來像這樣:加載實體ID CSV列水合實體NHibernate的

EntityId int : 1 
Countries1: "1,2,3,4,5" 
Countries2: "7,9,10,22" 

我想有NHibernate的加載identifed爲1,2,3的國家實體,4,5,7,9等,只要我的EntityId加載。

之所以這樣做,是因爲我們希望避免連接的擴散,因爲這些集合有幾十個。

+0

你可以給一些數據庫模式,類,映射? – Jaguar 2010-06-16 11:14:35

+0

+1正常情況下,我偏離了集合的字段,但我發現這可能很有用,並且hibernate中的實現看起來很簡單。 – mdma 2010-06-16 23:39:24

回答

1

提取國家必須發生的實體加載 - 你可以接受運行查詢來獲取這些? (您可以修改您的DAO以在獲取實體後運行查詢)。我問的原因是,只需運行查詢,而不是在加載實體時調用自定義代碼,這需要較少的「管道」和框架內部。

fecthing你的實體後,你有國家1,COUNTRY2列表,您可以運行類似查詢:

select c from Country c where c.id in (:Country1) 

傳:國家1作爲命名的參數。您也culd檢索所有行這兩組國家

select Entity e where e.id in (:Country1, :Country2) 

我希望,因爲他們是國家1 & COUNTRY2字符串可以使用的,但我有一種感覺,這是行不通的。如果是這樣,您應該將字符串轉換爲整數集合,並將該集合作爲查詢參數傳遞。

編輯:使「更透明」的「管道」以IInterceptor接口的形式出現。這可以讓你插上實體如何加載,保存,更新,刷新等你的實體將這個樣子

class MyEntity 
    { 
     IList<Country> Country1; 
     IList<Country> Country2; 
     // with public getter/setters 

     String Country1IDs; 
     String Country2IDs; 
     // protected getter and setter for NHibernate 
    } 

東西雖然域對象具有列表的兩種表示 - 實際的實體,以及ID列表,這與在實體中聲明常規ID字段時具有相同的入侵。集合(country1和Country2)不會保存在映射文件中。

有了這個,您可以提供一個IInterceptor實現,用於掛載加載和保存。在加載時,您可以獲取countryXID屬性的值,用於加載國家/地區列表(如上所述)。在保存時,您將各國的IList轉換爲ID列表並保存該值。

我找不到IInterceptor的文檔,但網上有很多項目使用它。該界面在this article中描述。

+0

這需要較少的(不)管道,但在我看來,這是一種錯誤的方法,因爲你失去了領域中的持續性無知。我試圖找出什麼是我需要放置的管道 – 2010-06-18 05:38:01

+0

我不確定你會得到你想要的,即非關係映射,但強制所有處理在持久層完成。另外請記住,hibernate可以將主實體和集合中的對象作爲單個SQL語句(使用連接)來獲取。如果避免了連接,那麼您將至少需要2次查詢。附加查詢的延遲可能比連接花費更多。 – mdma 2010-06-18 10:52:11

+0

在我遇到的問題中,實際上有14個這樣的組,而不是兩個,就像這個例子。我開始認爲這是不可能的。 – 2010-06-18 11:41:11

0

不,你不能,至少沒有默認的功能。

考慮到SQL中沒有SPLIT字符串函數,任何ORM都很難檢測由varchar列中的逗號分隔的謹慎整數值。如果你以某種方式克服了這個障礙,那麼你最好的辦法就是使用某種組件/自定義用戶類型,它仍然可以在'Country'表上進行連接的加密,最終獲取一個集合的國家實體...

...但我不確定它可以完成,它也意味着從頭開始寫持久性機制。

作爲一個便箋,我必須說我不明白設計決定;你反分貝數據庫,以及,因爲當聯接是壞的?

此外,另一個給定的答案將解決您的問題,無需重新設計您的數據庫,並且無需編寫大量實驗管道代碼。但是,它不會回答你的問題,因爲國家實體的水合作用

更新: 第二個想法,你可以作弊,至少對於選擇部分。 你可以做一個視圖將拆分值並顯示它們作爲單獨的行:

Entity-Country1 View: 
EntityId Country 
1  1 
1  2 
1  3 

Entity-Country2 View: 
EntityId Country 
1  7 
1  9 
1  10 

然後,你可以映射視圖