2012-05-21 89 views
1

我有三個表在我的數據庫NHibernate的queryover許多一對多

  1. 預約(ID,BunchOfFields)
  2. AppointmentAttendee(AppointmentId,使用ContactID)
  3. 聯繫(同上,ContactFields)
  4. 子查詢

約會可以有一個或多個參加者,這只是一個聯繫人。我有這些映射:

<class name="Appointment"> 
    <set name ="Attendees" table="AppointmentAttendee"> 
     <key column="AppointmentId"></key> 
     <many-to-many class="Cutter.Domain.Contact" column="ContactId"/> 

    </set> 
</class> 

我需要讓所有的約會(與所有與會者),其中有一個特定的聯繫人,並開始具體的時間表內。到目前爲止,我有:

 CurrentSession.QueryOver<Appointment>() 
      .Where(a=>a.StartDate>=start && a.StartDate<=end) 

我需要的基本上是這樣的SQL查詢

SELECT * 
FROM Appointment a 
LEFT JOIN OtherTables.... 
WHERE EXISTS (SELECT * FROM AppointmentAttendee att WHERE a.Id=att.AppointmentId and att.ContactId=?) 

編輯
到目前爲止,我想出了這一點:

var list=CurrentSession.QueryOver<Appointment>(() => appt) 
        .JoinAlias(()=>appt.Work,()=>work) 
        .Where(a => (a.StartDate >= start && a.StartDate <= end) 
        && work.Status==WorkStatus.Active) 
              .JoinQueryOver<Contact>(a => a.Attendees) 
        .Where(u => u.Id == assignedTo) 

        .List<Appointment>(); 

但我相信這是與參加者的約會,並會限制我回來的與會者。

編輯
一些更多的嘗試使我這個。 (注意:有些改變,從聯繫到用戶,但還是同樣的問題對象)

 Appointment appt=null; 
     WorkBase work=null; 

     var subQuery = QueryOver.Of<Appointment>() 
      .JoinQueryOver<User>(a => a.InternalAttendees)    
      .Where(u => u.Id == assignedTo) 
      .SelectList(a => a.Select(c=>c.Id)); 

     var list=CurrentSession.QueryOver<Appointment>(() => appt) 
      .JoinAlias(()=>appt.Work,()=>work) 
      .Where(a => (a.StartDate >= start && a.StartDate <= end) 
       && work.Status==WorkStatus.Active)    
      .WithSubquery.WhereExists(subQuery)    
      .List<Appointment>(); 

現在我得到了子查詢,但我怎麼子查詢連接到parentquery。 (需要子查詢引用外部約會ID)

此外,如果我可以做到這一點,而不必加入子查詢中的實體表似乎是錯誤的,當我需要的所有數據都在關聯表。

回答

4

只是在你的子查詢中增加一個條款,提及您的別名(其中(A => a.Id == appt.Id)):

Appointment appt=null; 
    WorkBase work=null; 

    var subQuery = QueryOver.Of<Appointment>() 
     .Where(a => a.Id == appt.Id) // restrict it to Appointment in outer query 
     .JoinQueryOver<User>(a => a.InternalAttendees)    
     .Where(u => u.Id == assignedTo)    
     .SelectList(a => a.Select(c=>c.Id)); 

    var list=CurrentSession.QueryOver<Appointment>(() => appt) 
     .JoinAlias(()=>appt.Work,()=>work) 
     .Where(a => (a.StartDate >= start && a.StartDate <= end) 
      && work.Status==WorkStatus.Active)    
     .WithSubquery.WhereExists(subQuery)    
     .List<Appointment>(); 
+0

你知道,如果有一種方法來強制NHibernate的到做子查詢而不加入其他兩個表? – JoshBerke

+1

使用您的映射,您可以使用Restrictions.Sql以非常醜陋的方式執行此操作,但您也可以使用hql執行它(但您失去了Criteria/QueryOver的功能),或者可以通過映射AppointmentAttendee表來實現它到一個類(使用複合鍵),但所有這些選項都是相當大的努力 - 取決於它對你有多重要 –

+0

在我需要優化系統之前不值得,這是一個更大的一小部分查詢這是越來越大,因爲它是...感謝您的建議! – JoshBerke