2012-12-20 208 views
4

我有一個類國防部,它有一個構件:NHibernate的:標準/子標準投影

ICollection<Event> EventList 

的類的事件有一個成員:

public virtual EventType Type { get; set; } 

類EvenType具有構件:

public virtual int Id 

我想使用NHibernate Criteria獲取Mod中所有具有1或2的ID的事件列表。我這樣做:

var subCriteria = DetachedCriteria.For<Mod>() 
    .Add(Restrictions.In("Event.Type", new int[] {1, 2 }) 
    ); 
criteria.Add(Subqueries.Exists(subCriteria)); 

但我得到一個運行時錯誤說 不能沒有突起的一個標準來使用子查詢。

所以,很好,但我不知道投影的內容。我可以找到如何進行預測的例子,但沒有什麼能夠真正解釋目的。我嘗試了各種各樣的東西,但都導致運行時錯誤:

消息:值不能爲空。 參數名:關鍵 來源:mscorlib程序 幫助鏈接: PARAMNAME:關鍵

我需要使用子查詢,因爲我會加入更多的時候這個工作。

你可以建議做什麼投影?

回答

7

如這裏記載:16.4. Associations這是可以做到這樣的:

IQueryOver<Mod, Event> query = session 
    .QueryOver<Mod>() 
    .JoinQueryOver<Event>(mod => mod.EventList) 
    .WhereRestrictionOn(evnt => evnt.Type.Id).IsIn(new object[] { 1, 2}); 

var result = query.List<Mod>(); 

編輯:純標準API:

var criteria = session.CreateCriteria<Mod>(); 
var sub = criteria.CreateCriteria("EventList", JoinType.LeftOuterJoin); 
    sub.Add(new InExpression("Type", new object[] { 1, 2 })); 

var result = criteria.List<Mod>(); 

使用分離的標準。在這種情況下,EventType必須具有屬性ModId或參考Mod實例。在子查詢中,我們必須返回有效的Mod.ID列表

var sub = DetachedCriteria 
.For<Event>() 
.Add(Restrictions.In("Type", new int[] {1, 2 })) // WHERE 
.SetProjection(Projections.Property("ModId")); // Mod.ID the SELECT clause 

var criteria = session.CreateCriteria<Mod>(); 
criteria.Add(Subqueries.PropertyIn("ID", sub)); // Mod.ID in (select 
var result = criteria.List<Mod>(); 
+0

Radim,感謝您的回覆。不過,我確實需要使用標準查詢。 – numberwang

+0

QueryOver位於Criteria API的頂層... *「QueryOver api,它結合了擴展方法和Lambda表達式的使用..提供了一個靜態的ICriteria API類型安全包裝器」* –

+0

再次,我感謝你。我的問題是關於預測。我已經有了一個標準實例,所以我不能像第二個例子那樣創建另一個標準實例,或者至少必須將這個標準添加到現有的實例中。 – numberwang