NHibernate QueryOver子查询仅返回最新记录

NHibernate QueryOver子查询仅返回最新记录,nhibernate,fluent-nhibernate,subquery,queryover,Nhibernate,Fluent Nhibernate,Subquery,Queryover,我在Nhibernate QueryOver中有一个查询,它返回了一组插曲对象(插曲是一个护理咒语),而这些对象又有一组插曲状态作为每个插曲的属性。然而,我想改变这一点,以便每一集只带回该集的最新状态更新,而不是所有更新 执行此操作的SQL语句如下所示: SELECT * FROM DIPEpisode e INNER JOIN DIPEpisodeStatus s on s.EpisodeID = e.SequenceID WHERE e.ClientID = '1000001' AN

我在Nhibernate QueryOver中有一个查询,它返回了一组插曲对象(插曲是一个护理咒语),而这些对象又有一组插曲状态作为每个插曲的属性。然而,我想改变这一点,以便每一集只带回该集的最新状态更新,而不是所有更新

执行此操作的SQL语句如下所示:

SELECT  *
FROM    DIPEpisode e
INNER JOIN DIPEpisodeStatus s on s.EpisodeID = e.SequenceID
WHERE e.ClientID = '1000001'
AND s.SequenceID IN (
SELECT TOP 1 SequenceID
FROM DIPEpisodeStatus s
WHERE s.EpisodeID = e.SequenceID
ORDER BY StatusRecordedDate DESC
)
我写了下面的查询,它几乎完全满足了我的需要

var statuses =
            QueryOver.Of<DIPEpisodeStatus>()
            .OrderBy(x => x.StatusRecordedDate).Desc
            .Select(x => x.Id).Take(1);

DIPEpisodeStatus statusAlias = null;

        return
            session.QueryOver<DIPEpisode>()
            .JoinQueryOver(x => x.DIPEpisodeStatuss, () => statusAlias)
            .Fetch(x => x.AgencyID).Eager
            .Fetch(x => x.DIPEpisodeStatuss).Eager
            .Where(e => e.ClientID.Id == this.clientId)
            .WithSubquery.WhereProperty(x => x.Id).Eq(statuses)
            .List();
如您所见,唯一缺少的是子查询中的where子句。为了生成这个额外的where子句并仅回拉最新的状态更新,我需要对查询进行哪些更改

谢谢


Ben

集合
dipepiodestatus
始终使用所有实体进行初始化,因为否则它将中断changetracking。您可以为集合定义筛选器,也可以返回所需的DTO。此外,由于无法在一条sql语句中加载和筛选,因此将忽略提取

如何使用DTO来实现这一点

// assuming SequneceID and StatusRecordedDate correlates
var subquery = QueryOver.Of<DIPEpisode>()
        .Where(e => e.ClientID.Id == this.clientId)
        .JoinAlias(e => e.DIPEpisodeStatuss, () => statusAlias)
        .Select(Projections.Max(() => statusAlias.SequenceID));

// or as in question
var subquery = QueryOver.Of<DIPEpisode>()
        .Where(e => e.ClientID.Id == this.clientId)
        .JoinAlias(e => e.DIPEpisodeStatuss, () => statusAlias)
        .OrderByDescending(() => statusAlias.StatusRecordedDate)
        .Select(() => statusAlias.SequenceID)
        .Take(1);

DIPEpisodeDto dto = null;
DIPEpisodeStatus statusAlias = null;
return session.QueryOver<DIPEpisode>()
        .Where(e => e.ClientID.Id == this.clientId)
        .JoinQueryOver(e => e.DIPEpisodeStatuss, () => statusAlias)
        .WithSubquery.WhereProperty(estatus => estatus.Id).Eq(statuses)
        .SelectList(list => list
            .Select(e => e.Whatever).WithAlias(() => dto.Whatever)
            .Select(() => statusAlias.SquenceId).WithAlias(() => dto.StatusId)
            ...
        )
        .TransFormUsing(Transformers.AliasToBean<DIPEpisodeDto>())
        .List();
//假设SequenceId和StatusRecordedDate相关
var subquery=QueryOver.Of()
.Where(e=>e.ClientID.Id==this.ClientID)
.JoinAlias(e=>e.dippenodestatus,()=>statusAlias)
.选择(projects.Max(()=>statusAlias.SequenceID));
//或者像刚才提到的那样
var subquery=QueryOver.Of()
.Where(e=>e.ClientID.Id==this.ClientID)
.JoinAlias(e=>e.dippenodestatus,()=>statusAlias)
.OrderByDescending(()=>statusAlias.StatusRecordedDate)
.选择(()=>statusAlias.SequenceID)
.采取(1)项措施;
dippesiodedto dto=null;
双偶合状态statusAlias=null;
return session.QueryOver()
.Where(e=>e.ClientID.Id==this.ClientID)
.JoinQueryOver(e=>e.dipepiodestatus,()=>statusAlias)
.WithSubquery.WhereProperty(estatus=>estatus.Id).Eq(状态)
.SelectList(list=>list
.Select(e=>e.Whatever).WithAlias(()=>dto.Whatever)
。选择(()=>statusAlias.SquenceId)。使用别名(()=>dto.StatusId)
...
)
.TransFormUsing(Transformers.AliasToBean())
.List();
或者使用LINQ

var query = from e in session.Query<DIPEpisode>()
            from s in e.DIPEpisodeStatuss
            where e.ClientID.Id == this.clientId
            where s.Id == (
                from e2 in session.Query<DIPEpisode>()
                from s2 in e2.DIPEpisodeStatuss
                orderby s2.StatusRecordedDate descending
                select s2.Id)
                .First()
            select new DIPEpisodeDto
            {
                e.Prop1,
                Status = s,
            };
return query.List<DIPEpisodeDto>();
var query=来自会话中的e.query()
源于e.Dippenodestatus中的s
其中e.ClientID.Id==this.ClientID
其中s.Id==(
来自会话中的e2.Query()
从e2中的s2开始
orderby s2.StatusRecordedDate降序
选择s2.Id)
.First()
选择新的DIPESODEDTO
{
e、 建议1,
状态=s,
};
返回query.List();

我继续修改返回的DTO。我循环遍历了每个epiosde dto,然后对EpioDE状态进行排序,并查看第一条记录,然后将其设置为epsode状态集合。这将加载所有stati或选择N+1,其中N是事件集合的计数
var query = from e in session.Query<DIPEpisode>()
            from s in e.DIPEpisodeStatuss
            where e.ClientID.Id == this.clientId
            where s.Id == (
                from e2 in session.Query<DIPEpisode>()
                from s2 in e2.DIPEpisodeStatuss
                orderby s2.StatusRecordedDate descending
                select s2.Id)
                .First()
            select new DIPEpisodeDto
            {
                e.Prop1,
                Status = s,
            };
return query.List<DIPEpisodeDto>();