【问题标题】:Multiple Subqueries With QueryOverQueryOver 的多个子查询
【发布时间】:2013-01-17 18:46:45
【问题描述】:

我需要帮助将此 sql 查询转换为 QueryOver Nhibernate 条件。

select distinct * from event e where e.name like '%req%' 
or e.Id in (select r.eventId from requirement r where r.name like '%req%') 
or e.Id in (select r.eventId from requirement r where r.id 
in (select s.requirementId from solution s where s.name like '%sol%'))

var queryOver = session.QueryOver<Event>()
                       .Where(x => x.Name.IsInsensitiveLike("%"+searchTerms[1]+"%"))
                       .OrderBy(x => x.CreatedOn).Asc;

到目前为止,我有主要查询,但找不到足够的关于如何添加子查询的参考资料。使用 joinQueryOver 没有成功。

事件与需求具有一对多的关系,需求与解决方案具有一对多的关系。

  Requirement reqAlias = null;
  Solution solAlias = null;

  var subQuery = QueryOver.Of<Event>()                                
      .JoinAlias(x => x.Requirements, () => reqAlias)
      .Where(x => x.Name.IsInsensitiveLike(searchTerms[2]))
      .JoinAlias(() => reqAlias.Solutions, () => solAlias)
      .Where(x => x.Name.IsInsensitiveLike(searchTerms[3]))
      .Select(Projections.Group<Event>(x => x.Id));

  var events = session.QueryOver<Event>()
      .Where(x => x.Name.IsInsensitiveLike(searchTerms[1]))
      .WithSubquery.WhereProperty(x => x.Id).In(subQuery)
      .List().ToList();

还是不行。

【问题讨论】:

    标签: nhibernate queryover


    【解决方案1】:

    当你使用IsInsensitiveLike时,NHibernate在解析后追加%,并使用lower做小写比较。在您的代码中,您自己附加了%,这会导致,

    select distinct * from event e where e.name like %lower('%req%')%
    

    这反过来又不起作用。

    此外,您有 3 个子查询,不是很大,因此您需要重构代码以解决这个问题:

    select r.eventId from requirement r where r.name like '%req%'
    

    var firstQuery = QueryOver.Of<Requirement>()                                
                              .Where(r => r.Name.IsInsensitiveLike(searchTerms[2]))
                              .Select(r => r.EventId);
    

    那么,

    select s.requirementId from solution s where s.name like '%sol%'
    

    var solutionQuery = QueryOver.Of<Solution>()                                
                               .Where(s => s.Name.IsInsensitiveLike(searchTerms[3]));
    

    那么,

    select r.eventId from requirement r where r.id 
    in (select s.requirementId from solution s where s.name like '%sol%')
    

    var requirementQuery = QueryOver.Of<Requirement>()
                                    .WithSubquery
                                    .WhereProperty(r => r.Id).In(solutionQuery)
                                    .Select(r => r.EventId);
    

    然后您需要使用Restrictions.Or 构造主查询以包含3 个查询。

    【讨论】:

    • rae1n 请看上面。我根据您的建议编辑了查询,但仍然没有运气。我想我很难弄清楚包括子查询。你能举个例子,当涉及两个以上的表时,如何编写子查询?
    • 谢谢,rae1n!这就像一个魅力。在我有时间再次处理它之前,我不得不使用 HQL 来完成它......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多