多对多的nHibernate queryover子查询

时间:2012-05-21 21:44:12

标签: nhibernate subquery queryover

我的数据库中有三个表

  1. 约会(Id,BunchOfFields)
  2. AppointmentAttendee(AppointmentId,ContactId)
  3. 联系人(Id,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>();
    

    现在我得到了子查询,但是如何将子查询连接到父查询。 (需要子查询来引用外部约会ID)

    如果我能在不必加入子查询中的实体表的情况下这样做会很好,当我需要的所有数据都在关联表中时,必须连接三个表是错误的。

1 个答案:

答案 0 :(得分:4)

只需在您的子查询中添加一个引用您的别名的子句(Where(a =&gt; 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>();