在NHibernate2.1中,如何使用要在select子句中使用的HQL获取集合中的第一项?
假设我有一个类产品:在NHibernate2.1中,如何使用要在select子句中使用的HQL获取集合中的第一项?,nhibernate,collections,hql,indexer,Nhibernate,Collections,Hql,Indexer,假设我有一个类产品: public class Product { public virtual string Name { get; set; } public virtual IList<Order> Orders { get; set; } } 假设它们已映射(使用Fluent NHibernate),如下所示: public class ProductMap : ClassMap<Product> { public ProductMap(
public class Product
{
public virtual string Name { get; set; }
public virtual IList<Order> Orders { get; set; }
}
假设它们已映射(使用Fluent 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);
}
}
我尝试了很多不同的方法,每个方法都有自己的错误
// 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和Fluent NHibernate 1.1.0.695好吧,这并不能回答您是否可以通过HQL通过集合中的索引提取项目的问题,但我确实找到了一个解决方案: 我需要集合中的第一个或最后一个项,一个具有min/max聚合函数的子查询就可以解决这个问题@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)
虽然不漂亮,但它确实有用。希望这对其他人有帮助 建议:想一想在SQL中该怎么做。我觉得你的映射有一个小问题。Product类可能不包含订单列表,但反之亦然。@Nathanpan-这就是一个例子。我绝不使用产品或订单。忘记上下文,想想练习。不过,谢谢@Mauricio-在SQL中,您的选项仅限于使用TOP(或LIMIT,取决于db)或在where、having或join子句中指定它。在不知道最后一项的情况下指定它涉及子选择,但在HQL中,这不仅是一个糟糕的解决方案,而且是不可能的解决方案,因为HQL不支持对子查询的限制。
// 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
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)