【问题标题】:Preventing multiple instance after inner join内部连接后防止多个实例
【发布时间】:2012-12-28 21:46:12
【问题描述】:

我有一个小问题,在连接到另一个表后,同一对象的多个实例。为了测试,我创建了一个Store 和两个Products(ManyToMany-Relation)。以下 sn-p 希望能描述我的问题。

var preResult = _session.QueryOver<Store>().List(); // One store

Product productAlias = null;
var result = _session.QueryOver<Store>()
    .JoinAlias(s => s.Products, () => productAlias)
    .List();                                        // Two instances of the same store

我什至认为这种行为是正确的,但如何防止多个实例?是否可以在查询中?


只是为了了解为什么我需要进行此不必要的连接:我想根据不同的条件扩展查询,类似于:

Product productAlias = null;
var query = _session.QueryOver<Store>().JoinAlias(s => s.Products, () => productAlias);
if (!string.IsNullOrWhiteSpace(criteria.ProductName))
{
    query.Where(Restrictions.On(() => productAlias.Name).IsInsensitiveLike(criteria.ProductName));
}

if (criteria.ProductType != null)
{
    query.Where(s => productAlias.Type == criteria.ProductType);
}

var result = query.List();

在这里我遇到了不同的问题,具体取决于标准。

【问题讨论】:

    标签: nhibernate queryover


    【解决方案1】:

    尝试在您的场景中使用Transformers.DistinctRootEntity 来消除笛卡尔积。

    Product productAlias = null;
    var query = _session.QueryOver<Store>()
                        .JoinAlias(s => s.Products, () => productAlias)
    
    query = query.TransformUsing(Transformers.DistinctRootEntity);
    
    var result = query.List();
    

    【讨论】:

      【解决方案2】:

      让我们将解决方案拆分为两个查询。

      1. 前一个QueryOver&lt;Store&gt;() 将正确返回一个不同的列表。更重要的是,通过设计它将支持分页(Take(),Skip())。
      2. 内部的将只返回一个商店 ID 列表,它完全符合任何标准...

      结果 SQL 将如下所示

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

      内部

      让我们从内部选择开始,NHibernate 分离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));
      }
      

      顶部

      一旦我们过滤了商店,我们就可以在顶部使用这个子查询

      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>();
      

      现在我们可以将任何过滤器应用于内部查询,并获取满足过滤条件的商店 ID 列表...同时使用不同的顶级查询...

      【讨论】:

        猜你喜欢
        • 2011-01-11
        • 1970-01-01
        • 1970-01-01
        • 2014-08-13
        • 2016-11-29
        • 2015-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多