Fetching Paginated Entity with Collection

99封情书 提交于 2019-11-29 16:47:24
Radim Köhler

This kind of queries should always use subquery instead of any type of JOIN. That also means, that the colleciton item has reference to parent (as in our case).

So, here we create the inner select for Vehicle:

var vehicles = DetachedCriteria.For<Vehicle>();
// add any amount or kind of WHERE parts
vehicles.Add(Restrictions.Eq("vehicle.Name", "super"))
// and essential SELECT Person ID
vehicles.SetProjection( Projections.Property("Owner.ID"));

Now, we can adjust the above query, to work only on a root/parent level:

var criteria = DetachedCriteria.For<Person>()

// instead of this
// .CreateAlias("Vehicles","vehicle", JoinType.InnerJoin)

// we will use subquery
.Add(Subqueries.PropertyIn("ID", vehicles));

// Wrong to use this approach at all
//.SetResultTransformer(new DistinctRootEntityResultTransformer())

.SetMaxResults(pageSize)
.SetFirstResult((page - 1) * pageSize)

That will create SELECT like this:

SELECT p....
FROM Person AS p
WHERE p.ID IN (
  SELECT v.OwnerId
  FROM Vehcile AS v
    WHERE v.Name = 'super' ...
)

See also:

And how to fetch the collection of Vehicles (until now just used for filtering)? The best (if not only) way is to use 1+1 SELECT statements. The easy and built-in solution is batch-size setting. Just mark the collection of Vehicles with this setting (e.g. batch-size="25") and with few more SELECT statements all data will be effectively loaded. See:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!