在Orchard中的NHibernate JoinQueryOver查询

时间:2014-12-02 16:37:17

标签: nhibernate orchardcms

我有一个Orchard网站。有两个连接的实体:代理(AgencyPartRecord)和设施(FacilityPartRecord),它们通过AgencyFacilitiesPartRecord与n-to-n连接。以下是相应的记录:

 public class AgencyPartRecord : ContentPartRecord
 {
    ...

    public virtual IList<AgencyFacilitiesPartRecord> AgencyFacilitiesPartRecords { get; set; }
    ...
}

public class AgencyFacilitiesPartRecord
{
    public virtual int Id { get; set; }

    public virtual AgencyPartRecord AgencyPartRecord { get; set; }

    public virtual FacilityPartRecord FacilityPartRecord { get; set; }
}

public class FacilityPartRecord : ContentPartRecord
{
    public virtual string Name { get; set; }

    public virtual string Description { get; set; }
}

现在我需要通过一组设施过滤掉代理商,这样只有选择了列表中所有设施的代理商。

最后我想得到这样的SQL:

SELECT *
FROM AgencyPartRecord
WHERE Id IN
(
    SELECT a.AgencyPartRecord_Id
    FROM AgencyFacilitiesPartRecord a              
    WHERE a.FacilityPartRecord_Id IN (... filter values here ...)
    GROUP BY a.AgencyPartRecord
    HAVING COUNT(a.Id) = <number of filter values>
)

我写了以下查询(filter.Facilities类型为List<int>):

IQueryOver<AgencyPartRecord, AgencyPartRecord> agencies = ... // apply other filters
AgencyFacilitiesPartRecord facility = null;    

var fsub = QueryOver.Of<AgencyFacilitiesPartRecord>(() => facility)                    
                .WhereRestrictionOn(r => r.FacilityPartRecord.Id).IsIn(filter.Facilities)
                .SelectList(list =>
                    list                            
                        .SelectGroup(a => a.AgencyPartRecord.Id)
                        .SelectCount(a => a.FacilityPartRecord.Id))
                .Where(Restrictions.Eq(
                    Projections.Count(
                        Projections.Property(() => facility.FacilityPartRecord.Id)), filter.Facilities.Count))
                .SelectList(list => list.Select(a => a.AgencyPartRecord.Id));


 agencies = agencies
                .WithSubquery.WhereProperty(a => a.Id).In(fsub);

问题是此查询在SQL中不生成GROUP BY子句:

SELECT ...  
FROM AgencyPartRecord this_ 
WHERE ...
    and this_.Id in 
(
    SELECT this_0_.AgencyPartRecord_id as y0_ 
    FROM AgencyFacilitiesPartRecord this_0_ 
    WHERE this_0_.FacilityPartRecord_id in (@p2, @p3) 
    HAVING count(this_0_.FacilityPartRecord_id) = @p4
) 

我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

我终于明白了! :) 正确的代码是:

AgencyFacilitiesPartRecord facility = null;

var fsub = QueryOver.Of<AgencyFacilitiesPartRecord>(() => facility)
    .WhereRestrictionOn(r => r.FacilityPartRecord.Id).IsIn(filter.Facilities)
    .SelectList(list => list
                   .SelectGroup(r => r.AgencyPartRecord.Id)
                )
    .Where(Restrictions.Eq(
        Projections.Count(Projections.Property(() => facility.FacilityPartRecord.Id)), filter.Facilities.Count));

agencies = agencies.WithSubquery.WhereProperty(a => a.Id).In(fsub);

Andrew,再次感谢您的QueryOver系列(http://blog.andrewawhitaker.com/queryover-series/)!