2010-07-06 50 views
1

說我們有2個實體EntityA和EntityB,其中有相關的表TableA和TableB。帶條件的嵌套選擇計數查詢

我要實現這個查詢:

select a.Id , (select count(b.Id) from TableB b where b.FKa = a.Id and b.AnotherField > 0) as TheCount 
from TableA a 

我很接近,因爲我寫了這個代碼:

var subCrit = DetachedCriteria.For<EntityB> 
             .Add<EntityB>(e => e.AnotherField > 0) 
             .SetProjection(LambdaProjection.Count<EntityB>(e => e.Id).As("TheCount")); 

var crit = Session.CreateCriteria<EntityA> 
         .SetProjection(LambdaProjection.GroupProperty<EntityA>(e => e.Id).As("Id), 
              Projections.SubQuery(subCrit)); 

如果我執行這個標準,我得到下面的SQL:

select a.Id as Id , (select count(b.Id) from TableB b where b.AnotherField > 0) as TheCount from TableA a 

正如你所看到的,它非常接近我想要實現的目標......問題(它是def這是一個大問題:D) 是子查詢和TableA實體之間沒有鏈接(其中b.FKa = a.Id)。 我無法找到一種方法,通過條件將子查詢與外部查詢相關聯。

有什麼建議嗎?

鉭很多

亞歷山德羅

編輯:

改變,我也可以做這樣的事情的觀點:

var crit = Session.CreateCriteria<EntityA>() 
        .CreateAlias<EntityB>(a => a.B,() => b); 
        .SetProjection(LambdaProjection.Count<A>(a => b.Id).As("TheCount"), 
        .SetProjection(LambdaProjection.GroupProperty<EntityA>(a => a.Id)); 

,這是生成以下sql:

select count(b.Id) as TheCount, a.Id as IDa 
from TableA a left outer join TableB b 
on a.Id = b.FKa 
group by a.Id 

但在這裏你可以看到附加的where子句b.AnotherField> 0缺失,我不知道如何插入它只是爲了計數。

希望這是明確的,再次感謝

+0

您是否考慮過使用nHibernate包?他們是nHibernate處理外鍵的方式。 – MikeTWebb 2010-07-06 16:33:01

+0

我想我應該已經發布了完整的場景..一路上我不能使用袋子那裏的域約束,我知道這是相當扭曲的場景,但這就是我必須實現的。 – 2010-07-07 08:19:12

+0

編輯與另一種可能的情況下的主要職位 – 2010-07-07 08:27:57

回答

0

我的建議是要改變SQL語句

SELECT a.is,計數(a.id) FROM tableA的 JOIN表B B關於a.id = b.fka AND b.af> 0 GROUP by a.ID

併爲它創建簡單的標準。

+0

不幸的是,我不能改變sql語句,因爲你建議在相同的SQL語句中,因爲我必須返回TableA的所有行,不僅僅是與附加的where子句一樣。我只需要計算滿足where子句的行。這就是伯爵子查詢的原因。 – 2010-07-07 08:17:15

+0

編輯與另一個可能的情況下的主要帖子 – 2010-07-07 08:28:56

+0

如果添加限制到別名b是應該工作。 – 2010-07-07 08:48:44

3

下面是解:

var condition = Expression.Gt("b.AnotherField",0); 
var conditionalProjection = Projections.Conditional(condition, Projections.Constant(1), Projections.Constant(0)); 

crit = Session.CreateCriteria<EntityA>() 
        .CreateAlias<EntityB>(a => a.B,() => b); 
        .SetProjection(Projections.Count(conditionalProjection).As("TheCount"), 
        (LambdaProjection.GroupProperty<EntityA>(a => a.Id)); 

,這是生成的SQL:作爲TheCount

選擇計數(情況b.AnotherField> 0,則1否則爲0)結束時,A.ID 從tableA的內連接表b b

希望它是有用的

歡呼

Alessandro

enter code here