我設法通過稍微調整原始的sql查詢來解決類似的問題。我已經結束了像這樣的東西(僞SQL代碼):
SELECT p.* FROM [Items] as p
WHERE EXISTS
(
SELECT [childId] as childNodeId FROM [Items] as q
WHERE p.[childId] = q.[childNodeId]
GROUP BY q.[childId]
HAVING p.[price] = MAX(q.[price])
)
這是QueryOver實現:
var subquery = QueryOver.Of(() => q)
.SelectList(list => list.SelectGroup(() => q.ChildId))
.Where(Restrictions.EqProperty(
Projections.Property(() => p.Price),
Projections.Max(() => q.Price)))
.And(Restrictions.EqProperty(
Projections.Property(() => p.ChildId),
Projections.Property(() => q.ChildId)));
從這裏你只需要通過別名,以便NHibernate的可以解決實體正確(僞代碼):
var filter = QueryOver.Of(() => p)
.WithSubquery.WhereExists(GetSubQuery(p, criteria...));
我希望這有助於您的具體情況。
UPDATE:標準API
var subquery = DetachedCriteria.For<Items>("q")
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("q.ChildId")))
.Add(Restrictions.EqProperty("p.Price", Projections.Max("q.Price")))
.Add(Restrictions.EqProperty("p.ChildId", "q.ChildId"));
var query = DetachedCriteria.For<Items>("p")
.Add(Subqueries.Exists(subquery));
不過我會建議堅持到QueryOver
版本,它更加直觀,您避免魔術字符串(特別是你沒有升級NH版) 。
請讓我知道這是否適合你。
我有點困惑。有沒有辦法使用ICriteria API而不是QueryOver來做到這一點?我之前沒有使用QueryOver,這可能是一個複雜的「第一個示例」:\ – GWLlosa
@GWLlosa:您能否確認我發佈在我的答案中的SQL適用於您,並且您得到完全相同的結果?我可以比嘗試用Criteria API重新編寫查詢,btw使用哪個版本的NHibernate? – MonkeyCoder
您擁有的SQL和我所做的SQL實際上會生成相同的行。根據DLL的細節,我使用NHibernate 3.1.0.4000。 – GWLlosa