2010-07-01 20 views
1

希望你能幫我解決一個映射問題。目前我有一個視圖返回如下內容:Fluent NHibernate:單個查詢的IEnumerable組件映射?

名稱|標題|價格|日期|格式| FormatPriority |

示例數據可能是:

Bob |積分| 340 | 01/01/2010 | BAR | 10 |
Bob |積分| 340 | 01/01/2010 | FOO | 20 |
Bob |積分| 340 | 01/01/2010 | WOO | 40 |

我要的是它看起來像這樣一個域模型:

字符串名稱;
string標題;
int Price;
DateTime Date;
IEnumerable格式;然後

格式類將有:

字符串類型
INT優先

在我們使用功能NHibernate(沒有自動配置)中的類映射方法的時刻。我們如何繪製這個圖?組件似乎不支持集合,這不是HasMany關係,因爲它作爲同一查詢的一部分回來。

任何想法??

感謝

回答

3

免責聲明:這是這樣一個龐大的黑客攻擊,它的痛苦,我將它張貼。

這是基於您提供的模式,因此可能需要修改以適應不同的設計。可能有更好的方法來做到這一點,但希望這應該讓你至少再次去。

問題是你的模型和查詢有一點不匹配。您的查詢返回多個行,您打算使用多個組件的單個實體,但NHibernate旨在將其解釋爲多個實體,每個實體都具有一個組件。

NHibernate支持組件集合,但僅當它們存儲在單獨的表/視圖中時才支持。這些組件通過外鍵連接回實體表。 如果你可以改變你的設計來支持這一點,請這樣做!

如果不是,我能想到的唯一選擇是您的視圖中的自我加入。它不會產生最優化的查詢,但它應該做到這一點。

你沒有提到你的實體被稱爲什麼,所以我已經去了Transaction

public class Transaction 
{ 
    public virtual string Name { get; set; } 
    public virtual string Title { get; set; } 
    public virtual decimal Price { get; set; } 
    public virtual DateTime Date { get; set; } 
    public virtual ISet<Format> Formats { get; set; } 
} 

public class Format 
{ 
    public virtual string Type { get; set; } 
    public virtual int Priority { get; set; } 

    // OVERRIDE EQUALITY MEMBERS! 
} 

我使用的映射是:

public class TransactionMap : ClassMap<Transaction> 
{ 
    public TransactionMap() 
    { 
     Table("vwTransactions"); 
     Id(x => x.Name); 
     Map(x => x.Title); 
     Map(x => x.Price); 
     Map(x => x.Date); 
     HasMany(x => x.Formats) 
      .Table("vwTransactions") 
      .KeyColumn("Name") 
      .Component(c => 
      { 
       c.Map(x => x.Type, "Format"); 
       c.Map(x => x.Priority, "FormatPriority"); 
      }) 
      .Fetch.Join(); 
    } 
} 

所以,你可以看到映射指着vwTransactions視圖。你沒有在模式中指定一個id,所以我用Name作爲標識(這很重要)。現在跳到HasMany,你可以看到也指向vwTransactions; NHibernate會看到這一點,並在視圖上進行自聯接。然後將密鑰列設置爲Name,與實體ID相同;這樣NHibernate將使用它來解析組件和實體之間的引用,而不是嘗試使用整數外鍵。 Fetch.Join將迫使NH熱切地取得這種關係,所以至少我們在那裏省了一點。最後值得注意的是,Formats屬性是ISet,如果你不這樣做,你最終會得到重複的組件。

如果您現在爲Transaction創建條件(或hql)查詢,您將使用其組件返回實體;但是,由於每個實體帶回多行,因此您將得到重複項。這是相當常見的,並且可以使用DistinctRootEntity轉換器輕鬆解決。

var transactions = session.CreateCriteria(typeof(Transaction)) 
    .SetResultTransformer(Transformers.DistinctRootEntity) 
    .List<Transaction>(); 

這應該是,你現在最終只有一個實體(基於你的數據集)與3個組件。

討厭,我知道。

+0

雖然我確信這會起作用,但我接受了您的建議並改變了視圖返回數據的方式。我現在每個關係都有觀點...希望它能工作:) – 2010-07-04 13:17:30

相關問題