nHibernate QueryOver中的GROUP BY和HAVING子句

时间:2013-01-30 10:40:33

标签: c# nhibernate queryover

我正在尝试用nHibernate QueryOver语言编写这个特定的sql查询,我对此不太熟悉:

SELECT MessageThreadId FROM MessageThreadAccesses
WHERE ProfileId IN (arr)
GROUP BY MessageThreadId
HAVING COUNT(MessageThreadId) = arr.Count

其中arr是一个整数数组(用户ID)我作为参数传递,而MessageThreadAccess实体看起来像这样:

public virtual MessageThread MessageThread { get; set; }
public virtual Profile Profile { get; set; }
....

在阅读了多个堆栈溢出线程并进行实验后,我得到了我的查询(尝试获取MessageThread对象 - 它应该总是只有一个或没有),但它仍然不起作用,我不确定是什么别的尝试。查询似乎总是返回MessageThreadAccess对象,但是当读取它的MessageThread属性时,它总是为NULL。

var access = Session.QueryOver<MessageThreadAccess>()
    .WhereRestrictionOn(x => x.Profile).IsIn(participants.ToArray())
    .Select(Projections.ProjectionList()
        .Add(Projections.Group<MessageThreadAccess>(x => x.MessageThread))
    )
    .Where(
        Restrictions.Eq(Projections.Count<MessageThreadAccess>(x => x.MessageThread.Id), participants.Count)
    )
    .TransformUsing(Transformers.AliasToBean<MessageThreadAccess>())
    .SingleOrDefault();

return Session.QueryOver<MessageThread>()
    .Where(x => x.Id == access.MessageThread.Id)
    .SingleOrDefault();

有人能指出我正确的方向,还是解释我做错了什么?

提前致谢。

1 个答案:

答案 0 :(得分:4)

我猜你可能会尝试使用DTO存储结果,而不是尝试将结果放在MessageThreadAccess中,而不是一个(没有配置文件)。

也许你可以试试:

public class MessageThreadCountDTO
{
    public MessageThread Thread { get; set; }
    public int Nb { get; set; }
}

然后

var profiles = new int[] { 1,2,3,4 };

MessageThreadCountDTO mtcDto = null;

var myResult = 
  _laSession.QueryOver<MessageThreadAccess>()
     .WhereRestrictionOn(x => x.Profile.Id).IsIn(profiles)
     .SelectList(list =>
         list.SelectGroup(x => x.MessageThread).WithAlias(() => mtcDto.Thread).
         SelectCount(x => x.MessageThread).WithAlias(() => mtcDto.Nb)
         )
     .Where(Restrictions.Eq(Projections.Count<MessageThreadAccess>(x => x.MessageThread), profiles.Count()))
     .TransformUsing(Transformers.AliasToBean<MessageThreadCountDTO>())
     .List<MessageThreadCountDTO>().FirstOrDefault();

将配置文件设置为Profile [],而不是int [],然后是以下行:

.WhereRestrictionOn(x => x.Profile.Id).IsIn(profiles)

应该是:

.WhereRestrictionOn(x => x.Profile).IsIn(profiles)

希望这会有所帮助