1

我的数据库中有三个表

  1. 约会(ID,BunchOfFields)
  2. AppointmentAttendee (AppointmentId,ContactId)
  3. 联系人(Id、ContactFields)

约会可以有 1 个或多个只是联系人的参加者。我有这些映射:

<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 Query

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)

如果我可以这样做而不必在子查询中加入实体表,当我需要的所有数据都在关联表中时,必须加入三个表似乎是错误的,这将是很好的。

4

1 回答 1

4

只需在引用别名的子查询中添加一个子句 (Where(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>();
于 2012-05-22T12:34:24.730 回答