2015-01-14 95 views
2

我有一個ICollection屬性被映射爲一個Set(使用代碼映射)的映射類。請注意,集合包含字符串而不是另一個映射實體。例如QueryOver IList <string> property

public class Item 
{ 
    public virtual ICollection<string> Facts { get; set; } 
} 

public class ItemMapping 
{ 
    public ItemMapping() 
    { 
     Set(x => x.Facts, m => 
     { 
      m.Key(k => k.Column("ItemId")); 
      m.Table("Facts"); 
     }, col => col.Element(m => 
     { 
      m.Column("Description"); 
      m.Type(NHibernateUtil.String); 
     })); 
    } 
} 

這項工程和事實上的項目的CRUD操作工作正常。但是,我想QueryOver <>數據庫中的事實(例如,檢索計數或前20個事實或檢索一些隨機事實),但由於沒有實體,我該怎麼做?我不想引入Fact實體,因爲它唯一的屬性是字符串。

回答

2

嗯,我的建議是:

引入實體。即使它只有一個屬性。稍後您可以擴展(與訂單,IsVisible)。如果你願意,那麼你的框架只能從one-to-manymany-to-one之間的關係中建立第一個公民對象。這意味着簡單的「框架概括,再利用......」

但我看到的是你不喜歡它(請至少嘗試重新思考) - 所以方式

NHibernate How do I query against an IList property?

哪裏試圖表明,(基於文檔)我們可以用神奇的詞,".elements"

17.1.4.1. Alias and property references

因此,這將觸及字符串元素在你的情況下,查詢

Item item = null; 
string fact = null; 
var demos = session.QueryOver<Item>(() => item) 
     .JoinAlias(i => i.Facts,() => fact) 

     // instead of this 
     // .Add(Restrictions.Eq("fact", "abc")) 

     // we can use the .elements keyword 
     .Where(Restrictions.Eq("fact.elements", "abc")) 

     .List<Item>(); 

所以,這樣一來,就可以得到項目其中確實有一些事實等於​​

+0

我已經接受了這個答案,因爲它可能是解決這個問題的最好方法。我不想將它映射到實體的原因是因爲它在我看來違背了YAGNI/KISS原則,即您可以稍後擴展它。所以我最終將它映射爲它,因爲它確實給了我額外的QueryOver <>()靈活性/ options .. – Chet

+0

即使最簡單的代碼,我也無法複製這個答案。我在其他地方讀過,可能會出現一個在舊版NHib中出現混淆的錯誤(<4?)。無論如何,我不得不創建一個類來表示字符串項,然後可以做我的QueryOver沒問題。有點糟糕,但至少我有類型安全。 – ctrlplusb

1

非實體必須由其實體查詢並選擇。例如,要獲得前20個事實:

string fact = null; 
var first20facts = session.QueryOver<Item>() 
    .JoinAlias(i => i.Facts,() => fact) 
    .OrderBy(() => fact).Asc 
    .Take(20) 
    .Select(() => fact) 
    .List<string>(); 

或者,您還可以將Fact只讀實體映射到查詢中。

相關問題