【发布时间】:2009-09-02 23:07:25
【问题描述】:
采用一个相当简单的域模型 Orders、items 和 shipping ,其中 Order 是根实体,而 shipping 是根实体。我想查找给定订单的所有货件。查询非常简单,但我看到 NHibernate 出现不良行为。
模型
public class Order
{
public Order(){ Items = new List<LineItem>(); }
public virtual int Id { get; private set; }
public virtual DateTime Created { get; set; }
public virtual IList<LineItem> Items { get; private set; }
}
public class LineItem
{
public virtual int Id { get; private set; }
public virtual int Quantity { get; set; }
public virtual Order Order { get; set; }
}
public class Shipment
{
public virtual int Id { get; private set; }
public virtual DateTime Date { get; set; }
public virtual LineItem LineItem { get; set; }
}
LINQ
在这个查询中使用 NHibernate.Linq:
var shipments = from shipment in session.Linq<Shipment>()
where shipment.LineItem.Order == order
select shipment;
以下 SQL 查询的结果:
SELECT this_.Id as Id5_2_,
this_.Date as Date5_2_,
this_.LineItem_id as LineItem3_5_2_,
lineitem1_.Id as Id4_0_,
lineitem1_.Quantity as Quantity4_0_,
lineitem1_.Order_id as Order3_4_0_,
order2_.Id as Id3_1_,
order2_.Created as Created3_1_,
order2_.IsClosed as IsClosed3_1_
FROM [Shipment] this_
left outer join [LineItem] lineitem1_
on this_.LineItem_id = lineitem1_.Id
left outer join [Order] order2_
on lineitem1_.Order_id = order2_.Id
WHERE lineitem1_.Order_id = 1 /* @p0 */
生成的 Shipment 对象是正确的,但查询加载了太多数据,因为我只对发货日期感兴趣。订单和订单项数据会立即被丢弃并且永远不会使用。我已经尝试使用延迟加载以及我可以在网上找到的所有获取策略,但我无法让它简单地返回基本数据。
如何减少 SQL 查询中的噪音,使其仅加载货件数据和订单项的主键以支持延迟加载?更像是这样的:
SELECT this_.Id as Id5_2_,
this_.Date as Date5_2_,
this_.LineItem_id as LineItem3_5_2_,
lineitem1_.Id as Id4_0_,
FROM [Shipment] this_
inner outer join [LineItem] lineitem1_
on this_.LineItem_id = lineitem1_.Id
WHERE lineitem1_.Order_id = 1 /* @p0 */
自定义 SQL 查询(更新)
使用如下所示的自定义 SQL 查询可以获得所需的性能和正确的行为。然而,它有点违背了 ORM 的目的。为什么 NHibernate 不能生成这么简单的查询?
Session
.CreateSQLQuery(
@"SELECT SH.*, LI.Id FROM Shipment SH
INNER JOIN LineItem LI ON LI.Id = SH.LineItem_id
WHERE LI.Order_id = ?" )
.SetInt32( 0, order.Id )
.List<Shipment>();
【问题讨论】:
-
您可以发布您的 HBM 文件吗?
标签: nhibernate join