2013-02-12 8 views
2

SQL查詢:是否可以使用NH QueryOver在一個查詢中提取已加入的實體?

select B.* from A inner join B on A.b_id = B.id where A.x in (1,2,3) 

一個< - >乙的關係是多到一個

我需要用A來過濾,但獲取相關B.

UPDATE:

我試過這個NH QueryOver

Session.QueryOver<A>.Where(a => a.x.IsIn(array)).JoinQueryOver(a => a.B).Select(a => a.B).List<B>() 

b它會產生N + 1個查詢序列:第一個查詢獲取相關Bs的ID,其他查詢則通過ID(通過NHProf分析)逐個獲取相關Bs。我希望它一次性提取Bs列表。

更新2:

現在我工作圍繞這與子查詢

Session.QueryOver(() => b).WithSubquery.WhereExists(QueryOver.Of<A>().Where(a => a.x.IsIn(array)).And(a => a.b_id == b.id).Select(a => a.id)).List<B>() 

,但我還是希望能看到QueryOver 的例子不子查詢,我傾向於認爲子查詢效率不高。

+0

是的,這是可能的,我認爲你至少應該先給它一個! – Rippo 2013-02-12 10:44:34

+0

問題已更新。 – ivan 2013-02-12 10:58:15

+0

嘗試在Where(a => a.x.IsIn(array))之後添加Fetch(a => a.B).Eager以擺脫N + 1問題。 – 2013-02-12 11:06:42

回答

2

這工作(至少在我的測試應用程序):

var list = session.QueryOver<A>() 
        .Where(a => a.X.IsIn(array)) 
        .Fetch(x => x.B).Eager 
        .List<A>() 
        .Select(x => x.B); 

注意的。選擇()語句是正常的LINQ語句,而不是NHibernate的一部分。

生成的SQL:

SELECT 
    this_.Id as Id0_1_, 
    this_.B as B0_1_, 
    this_.X as X0_1_, 
    b2_.Id as Id1_0_, 
    b2_.SomeValue as SomeValue1_0_ 
FROM A this_ left outer join B b2_ on this_.B=b2_.Id 
WHERE this_.X in (?, ?, ?) 

這不是最佳的,如果A是一個非常大的類的,當然。

的使用子查詢NHibernate的,唯一的解決辦法:

var candidates = QueryOver.Of<A>() 
          .Where(a => a.X.IsIn(array)) 
          .Select(x => x.B.Id); 

var list = session.QueryOver<B>() 
        .WithSubquery.WhereProperty(x => x.Id).In(candidates).List(); 

我會試圖找到爲什麼最明顯的解決方案(只是增加取()躍躍欲試。)不能按預期工作的原因。敬請關注!

+1

cool,等待乾淨的NH解決方案 – ivan 2013-02-13 09:45:50

+0

選項與熱切的關聯獲取和LINQ-ing是一個在某些情況下,子查詢是非常好的選擇,謝謝! – ivan 2013-02-19 08:02:40

相關問題