【问题标题】:Translating HQL into another nHibernate query form将 HQL 转换为另一个 nHibernate 查询表单
【发布时间】:2012-01-30 15:18:43
【问题描述】:

HQL 查询是:

from BusinessObject as businessobject
    left outer join businessobject.BussinesPartner as businesspartner
    left outer join businessobject.Document as document
    left outer join businessobject.Group as group ";
where businessobject.Date >= :datefrom and businessobject.Date <= :dateto
     and (:filter = ''
          or :filter is null 
          or businesspartner.Name like '%' || :filter || '%'
          or group.Name like '%' || :filter || '%'
          or document.Name like '%' || :filter || '%')

我不想使用 HQL。我还想要一个强类型的结果集合,而不使用不方便和混乱的 SetResultTransformer。我更喜欢使用 Query(),但我不知道如何强制外连接。

当我以 Query() 形式编写时,它不会返回日期在正确范围内的结果,并且如果例如 BusinessPartner 为空,则 filter = ""。虽然这些对象的“where”逻辑表达式为真,但由于使用了内部连接,它们看起来无论如何都不在结果集中:

session.Query<BusinessObject>()
       .Where(x =>
             (x.Date >= criteria.DateFrom && x.Date <= criteria.DateTo
          && (criteria.Filter == ""
             || x.BusinessPartner.Name.Contains(criteria.Filter)
             || x.Group.Name.Contains(criteria.Filter)
             || x.Document.Name.Contains(criteria.Filter))))

这不起作用,因为在引用 BusinessPartner、Group 或 Document 的字段中包含 null 的任何行都不会返回(表示内部连接)。

是否可以用 Query() 做我想做的事?还是有标准?

【问题讨论】:

    标签: c# linq nhibernate


    【解决方案1】:

    我不知道 Query() 但是使用 ICriteria 您可以控制 JOIN 的类型并使用 CreateAlias 获得强类型结果。

    ICriterion conjunction = Restrictions.Conjunction();
    conjunction.Add(Restrictions.Contains(criteria.Filter),"BusinessPartner.Name");
    conjunction.Add(Restrictions.Contains(criteria.Filter),"Group.Name");
    conjunction.Add(Restrictions.Contains(criteria.Filter),"Document.Name");
    
     ICriteria query = ICriteria.CreateCriteria
    .CreateAlias("BusinessPartner", "BusinessPartner", JoinType.LeftOuterJoin)
    .CreateAlias("Group", "Group", JoinType.LeftOuterJoin)
    .CreateAlias("Document", "Document", JoinType.LeftOuterJoin)
    .Add(Restrictions.Between(criteria.DateFrom,criteria.DateTo),"Date")
    .Add(conjunction));
    
    List<BusinessObject> results = query.List<BusinessObject>();
    

    【讨论】:

    • 它可能需要一点重构,我不在办公室。
    • 这看起来可能会起作用(明天上班试试,我这里没有数据库)。但是,它通过不使用 SetResultTransformer 来避免我试图避免的事情——当我已经通过写出映射以不同的形式提供此信息时,为每个字段创建一个别名。这就是为什么我更喜欢使用通用查询,它使用映射自动将值分配给正确的字段。但是我可能最终还是会这样做,因为我需要外部连接。
    猜你喜欢
    • 2011-09-24
    • 2013-07-02
    • 2014-06-26
    • 2020-08-23
    • 1970-01-01
    • 2020-11-12
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多