【问题标题】:NHibernate QueryOver to select one entity for each group entityNHibernate QueryOver 为每个组实体选择一个实体
【发布时间】:2011-09-07 14:34:52
【问题描述】:

我正在写旅游博客的一部分,所以我有两个实体:地点和照片,一对多,所以每个地方都可以有多张照片,但单张照片属于一个地方。

我的目标是创建摘要:最后添加了 3 个地方,并且每个地方我都想要一张照片(例如,ID 较低的照片,没关系)。重要的是不仅要有照片的 id,还有更多信息(列),如照片标签、照片路径等。

在 MS SQL 2008 中使用 SQL 可以通过使用排名函数来完成:

select top 3 * from
(
SELECT     p.id, p.label, p.VisitDate, ph.id AS photo_id, ph.Label, ph.Path,
RANK() OVER (PARTITION BY p.id ORDER BY ph.id) AS _rank
FROM         place AS p INNER JOIN
                      photo AS ph ON p.id = ph.place_id
) ranked
where _rank = 1
order by VisitDate desc

或者不用排名也可以解决:

SELECT     TOP (3) a.id AS ida, z.id AS idz, z.etykieta, z.sciezka, a.data_odwiedzenia
FROM         place AS a INNER JOIN
                      photo AS z ON a.id = z.id_atrakcji
and z.id in 
(
SELECT  min(z.id) AS idz
FROM photo z 
where z.id_atrakcji in (select top 3 a.id from place a order by a.data_dodania desc)
group by z.id_atrakcji
)
ORDER BY a.data_odwiedzenia DESC

我开始写这个查询没有排名,但我卡住了。

    summaryList =
 session.QueryOver(() => placeAlias)
.JoinAlias(o => o.Photos, () => photoAlias)
.SelectList(list => list
.Select(() => placeAlias.Id).WithAlias(() => summaryAlias.PlaceId)
.Select(() => placeAlias.Etykieta).WithAlias(() => summaryAlias.PlaceName)
.Select(() => photoAlias.Etykieta).WithAlias(() => summaryAlias.PhotoLabel)
.Select(() => photoAlias.Id).WithAlias(() => summaryAlias.PhotoId)
)
.OrderByAlias(() => placeAlias.VisitDate).Desc
.WithSubquery.WhereProperty(x => x.Id).In(lastPlaces)
.TransformUsing(Transformers.AliasToBean<PlacesSummary>())
.List<PlacesSummary>();

你能帮我解决这个问题吗?如何编写 lastPlaces queryover 或者可能有另一种方法?

问候, 马可

【问题讨论】:

    标签: nhibernate queryover summary


    【解决方案1】:
    var subquery = QueryOver.Of(() => photoAlias)
        .Where(photo => photo.Place.Id == placeAlias.Id)
        .Select(Projections.Max<Photo>(photo => photo.Id));
    
    var summaryList = session.QueryOver(() => placeAlias)
        .OrderBy(() => placeAlias.VisitDate).Desc
        .JoinQueryOver(() => placeAlias.Photos, () => photoAlias)
        .WithSubquery.WhereProperty(photo => photo.Id).Eq(subquery)
        .SelectList(list => list
            .Select(() => placeAlias.Id).WithAlias(() => summaryAlias.PlaceId)
            .Select(() => placeAlias.Etykieta).WithAlias(() => summaryAlias.PlaceName)
            .Select(() => photoAlias.Etykieta).WithAlias(() => summaryAlias.PhotoLabel)
            .Select(() => photoAlias.Id).WithAlias(() => summaryAlias.PhotoId)
        )
        .TransformUsing(Transformers.AliasToBean<PlacesSummary>())
        .List<PlacesSummary>();
    

    暂时无法测试

    【讨论】:

      【解决方案2】:

      它不能正常工作,但它非常接近:

      summaryList =
      session.QueryOver(() => placeAlias)
      .OrderByAlias(() => placeAlias.VisitDate).Desc
      .JoinAlias(o => o.Photos, () => photoAlias)
      **.WithSubquery.WhereProperty(()=> photoAlias.Id).Eq(subquery)**
      .SelectList(list => list
      .Select(() => placeAlias.Id).WithAlias(() => summaryAlias.PlaceId)
      .Select(() => placeAlias.Etykieta).WithAlias(() => summaryAlias.PlaceName)
      .Select(() => photoAlias.Etykieta).WithAlias(() => summaryAlias.PhotoLabel)
      .Select(() => photoAlias.Id).WithAlias(() => summaryAlias.PhotoId))
      .TransformUsing(Transformers.AliasToBean<PlacesSummary>())
      .Take(3)
      .List<PlacesSummary>();
      

      只有一行 .WithSubquery 不同,它最初指的是 Place 而应该指的是 Photo。现在它可以工作了,它会生成以下 SQL:

      SELECT TOP (3)  this_.id as y0_, this_.PlaceName as y1_, photoalias1_.PhotoName as y2_, photoalias1_.id as y3_ 
      FROM [place] this_ inner join [photo] photoalias1_ on this_.id=photoalias1_.id_place 
      WHERE photoalias1_.id = (SELECT min(this_0_.id) as y0_ FROM [photo] this_0_ WHERE this_0_.id_place = this_.id) 
      ORDER BY this_.DateVisit desc
      

      效果很好,但我还有一个问题:

      如何在QueryOver这样的SQL中重写:

      SELECT  min(id)
      FROM photo
      where id in (... it doesn't matter what's here ...)
      group by place_id
      

      所以我只想要照片 ID 列表(仅列),并且此查询将用作另一个查询中的子查询。可以通过QueryOver语法来完成吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-22
        • 2012-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多