2011-03-30 44 views
2

假設我有一類產品:在NHibernate 2.1中,如何使用HQL在選擇子句中使用HQL獲取集合中的第一個項目?

public class Product 
{ 
    public virtual string Name { get; set; } 
    public virtual IList<Order> Orders { get; set; } 
} 

和Order類:

public class Order 
{ 
    public virtual float Amount { get; set; } 
    public virtual DateTime Created { get; set; } 
} 

假設它們映射(使用功能NHibernate)如下:

public class ProductMap : ClassMap<Product> 
{ 
    public ProductMap() 
    { 
     Map(x => x.Name); 
     HasMany(x => x.Orders).OrderBy("created desc"); 
    } 
} 

public class OrderMap: ClassMap<Order> 
{ 
    public OrderMap() 
    { 
     Map(x => x.Amount); 
     Map(x => x.Created); 
    } 
} 

如果我想以獲取最後OrderProduct以及AmountName(其由於m y映射爲OrderBy子句,是第一個)在HQL語句中,我將如何去解決它?類似的東西(出於說明的目的):

select p.Name, p.Orders[0].Amount from Product p 

我試過很多變化,每個都有自己的錯誤。

// Throws 'Property index does not exist in collection' 
select p.Name, order.Amount from Product p join p.Orders as order where index(order) = 0 

// Throws 'Antlr.Runtime.MismatchedTreeNodeException' on the brackets in p.Orders[0]. 
select p.Name, p.Orders[0] from Product P 

// Throws 'Object reference not set to an instance of an object' 
select p.Name, p.Orders[0].Amount from Product p 

// Works fine, but not what I want 
select p.name, order.Amount from Product p join p.Orders as order 

在這個例子中,我可以擺脫使用SetMaxResults(),但是,在現實中,查詢要複雜得多,返回多行 - 所以這不會做。

我覺得我在這裏錯過了一些基本的東西,所以任何幫助表示讚賞。

使用: 的NHibernate 2.1.2.4000和功能NHibernate 1.1.0.695

+1

建議:想你會怎麼做在SQL中。 – 2011-03-31 00:10:17

+0

我覺得你的映射有一個小問題。產品類別可能不包含訂單列表,但會通過。 – Nathanphan 2011-03-31 00:42:19

+0

@Nathanphan - 這是一個例子。我絕不使用產品或訂單。忘記背景,想想練習。不過謝謝! – 2011-03-31 14:27:36

回答

1

那麼,這並沒有回答您是否可以通過它的索引集合中通過HQL拉一個項目的問題,但我爲我的實現找到了解決方案:

我需要集合中的第一個或最後一個項目,並且具有最小/最大聚合函數的子查詢來救援。 @Mauricio讓我關於SQL替代思考得更深一些,就有了答案:

select p.Name, order.Amount from Product p join p.Orders as order 
where order.Id = (select max(order2.Id) from Product p2 
join p2.Orders as order2 where p2.Id = p.Id) 

這不是很漂亮,但它的工作。希望這可以幫助別人...