NHibernate - 混合子查询和急切的左连接

时间:2012-01-10 22:11:16

标签: sql hibernate nhibernate fluent-nhibernate nhibernate-mapping

考虑这个数据库模型:

Product         Payment         Info          
-------         -------         --------
Id              Id              Id
Name            Value           Year
                Date            Description
                ProductId       ProductId

我的愿望是从数据库查询所有产品(按名称),急切加载付款以及

通过某个参数添加Info中的描述。 (Postgre)SQL看起来像这样:

Select product.Id, product.Name, payment.Value, payment.Date,
   (select inf.Description from Info inf 
    where inf.ProductId = product.Id where inf.Year = 2010 limit 1) as Description
from product left outer join payment on product.Id = payment.ProductId
where product.Name like ?

但是,我有两个主要问题:

  1. 如何在NHibernate中进行查询(无论是在SQL,HQL,Criteria API,QueryOver,LINQ等)?
  2. 我怀疑我必须预测Category.Description,所以我提出了这个:

    var subquery = DetachedCriteria.For<Info>("inf")
        .Add(Restrictions.EqProperty("inf.Product.Id", "p.Id"))
        .Add(Restrictions.Eq("Year", 2010)).
    .SetProjection(Projections.Property("inf.Description"));
    
    var criteria = session.CreateCriteria<Product>("p")
        .Add(Restrictions.Eq("Product.Id", 12345678))
        .SetProjection(
            Projections.Property("p.Id"),
            Projections.Property("p.Name"),
            Projections.Property("p.Payments"),
            Projections.Alias(Projections.SubQuery(subquery), "p.Description"));
    
    criteria.SetFetchMode("p.Payments", FetchMode.Eager);
    

    然而,这不起作用。如何创建子查询并仍然急于获取付款?

    1. 如何从结果集创建实体(bean)?
    2. 我希望从结果中创建以下实体:

      public class Product
      {
          public virtual int Id { get; set; }
          public virtual string Name { get; set; }
          public virtual string Description { get; set; }
          public virtual IList<Payment> Payments { get; set; }
      }
      
      public class Payment
      {
          public virtual int Id { get; set; }
          public virtual Product Product { get; set; }
          public virtual double Value { get; set; }
          public virtual DateTime Date { get; set; }
      }
      

      由于我正在使用投影,这看起来像AliasToBeanResultTransformer的情况,但是,它似乎无法识别我的左连接(急切加载的付款)。

      请指教。

      谢谢!

1 个答案:

答案 0 :(得分:2)

您可以使用NHibernate公式来获取描述的值

<property name="Description" type="Type,Namespace" formula="(select inf.Description from Info inf 
where inf.ProductId = product.Id where inf.Year = 2010 limit 1)"/>

参考:How to map a property with formula in NHibernate?