Preventing multiple instance after inner join

隐身守侯 提交于 2019-11-28 14:07:58

Let's split solution into two queries.

  1. Top one QueryOver<Store>() will be correctly returning just a distinct list. And what's more, by design it will support paging (Take(), Skip()).
  2. The inner one, will be returning just a list of Store IDs, which fully meet whatever criteria...

The result SQL will look like this

SELECT ... // top one 
FROM Store
WHERE StoreID IN ( SELECT StoreID ...) // inner one

Inner

Let's start with the inner select, the NHibernate detached QueryOver:

Store storeAlias = null;
Product productAlias = null;

// detached query, resulting in a set of searched StoreID 
var subQuery = QueryOver.Of<Store>(() => storeAlias)
    .JoinAlias((s) => s.Products, () => productAlias)
    .Select((s) => s.ID); // ID projection

if (!string.IsNullOrWhiteSpace(criteria.ProductName))
{
    subQuery.Where(Restrictions.On(() => productAlias.Code)
        .IsInsensitiveLike(criteria.ProductName));
}

Top

Once we have filtered the Store we can use this subquery in top one

var query = session.QueryOver<Store>()
   // IN clause
   .Where(Subqueries.PropertyIn("ID", subQuery.DetachedCriteria))
   .Skip(100) 
   .Take(50) // paging over already distinct resultset
   ;

var result = query.List<Store>();

And now we can apply whatever filter to inner query, and get list of Store IDs which do meet filter criteria... while working with top query, which is distinct...

Try using Transformers.DistinctRootEntity in your scenario to eliminate the cartesian product.

Product productAlias = null;
var query = _session.QueryOver<Store>()
                    .JoinAlias(s => s.Products, () => productAlias)

query = query.TransformUsing(Transformers.DistinctRootEntity);

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