nHibernate QueryOver中的GROUP BY和HAVING子句

Mat*_*tej 8 c# nhibernate queryover

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

SELECT MessageThreadId FROM MessageThreadAccesses
WHERE ProfileId IN (arr)
GROUP BY MessageThreadId
HAVING COUNT(MessageThreadId) = arr.Count
Run Code Online (Sandbox Code Playgroud)

其中arr是一个整数数组(用户ID)我作为参数传递,而MessageThreadAccess实体如下所示:

public virtual MessageThread MessageThread { get; set; }
public virtual Profile Profile { get; set; }
....
Run Code Online (Sandbox Code Playgroud)

在阅读了多个堆栈溢出线程并进行实验后,我得到了我的查询(尝试获取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();
Run Code Online (Sandbox Code Playgroud)

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

提前致谢.

jbl*_*jbl 4

我想您可能会尝试使用 DTO 来存储结果,而不是尝试将结果放入 MessageThreadAccess(当结果不是一个(无配置文件)时)。

也许你可以尝试:

public class MessageThreadCountDTO
{
    public MessageThread Thread { get; set; }
    public int Nb { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后

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();
Run Code Online (Sandbox Code Playgroud)

如果配置文件是 Profile[],而不是 int[],则以下行:

.WhereRestrictionOn(x => x.Profile.Id).IsIn(profiles)
Run Code Online (Sandbox Code Playgroud)

应该 :

.WhereRestrictionOn(x => x.Profile).IsIn(profiles)
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助