在NHibernate中有一个看起来很棒的N + 1选择问题。我正在执行一个查询,在那里我要求一组实体,其中一个链接的属性为null。在本例中,我并不需要将NHibernate作为唯一的链接属性返回,以便选择正确的数据。导致N + 1的NHibernate QueryOver.List
第一实体是预订窗口
public class BookingWindow : Entity<BookingWindow>
{
// Blah blah blah
/// <summary>
/// Gets or sets the booking order item.
/// </summary>
/// <value>
/// The booking order item.
/// </value>
public virtual BookingWindowOrderItem BookingOrderItem { get; set; }
}
而且BookingWindowOrderItem如下
public class BookingWindowOrderItem : OrderItem
{
// Blah blah blah
public virtual BookingWindow BookingWindow { get; set; }
}
这里是各自映射
public BookingWindowMap()
{
this.Schema("Customer");
this.Table("BookingWindows");
this.Id(x => x.Id).GeneratedBy.Guid();
this.Component(x => x.WindowPeriod, m =>
{
m.Map(x => x.Min, "StartTime");
m.Map(x => x.Max, "EndTime");
});
this.References(window => window.BookingOrderItem).PropertyRef("BookingWindow").Column("Id").LazyLoad().Nullable().ReadOnly();
this.Map(x => x.Price);
this.References(x => x.CustomerRoom).ForeignKey("RoomId").Column("RoomId");
}
而且
public BookingWindowOrderItemMap()
{
this.DiscriminatorValue(1);
this.References(x => x.BookingWindow).LazyLoad().Column("OrderItemForeignId").ForeignKey("OrderItemForeignId");
}
现在,当我执行以下查询时,我找回没有订单项目的正确预订窗口。
Session.QueryOver<BookingWindow>().Where(w => w.CustomerRoom.Id == Guid.Parse(roomId)).Left.JoinQueryOver(bw => bw.BookingOrderItem).WhereRestrictionOn(item => item.Id).IsNull.List<BookingWindow>();
所以第一个查询被发给数据库,像这样(被选中的订单项目列这是一个有点讨厌,但真正的问题是在一分钟内)
SELECT this_.Id为Id2_1_, this_.Rrice为Price2_1_,this_.RoomId为RoomId2_1_,this_.StartTime为StartTime2_1_,this_.EndTime为EndTime2_1_,bookingwin1_.Id为Id4_0_,bookingwin1_.Price为Price4_0_,bookingwin1_.Description为Descript4_4_0_,bookingwin1_.OrderId为OrderId4_0_,bookingwin1_。 OrderItemParentId为OrderIte6_4_0_,bookingwin1_.OrderItemForeignId为OrderIte7_4_0_从Customer.BookingWindows this_左外部联接Payment.OrderItem bookingwin1_ on this_.Id = bookingwin1_.OrderItemForeignI d和bookingwin1_.OrderItemTypeId ='1'where_.RoomId =?并且bookingwin1_.Id为空
但是,对于每个预订窗口返回的链接订单项目都有额外的选择,即使我没有要求或需要它。这发生在查询方法内,所以我没有做任何手动迭代返回的预订窗口。
SELECT bookingwin0_.Id如Id4_0_,bookingwin0_.Price如Price4_0_,bookingwin0_.Description如Descript4_4_0_,bookingwin0_.OrderId如OrderId4_0_,bookingwin0_.OrderItemParentId如OrderIte6_4_0_,bookingwin0_.OrderItemForeignId如OrderIte7_4_0_ FROM Payment.OrderItem bookingwin0_ WHERE bookingwin0_.OrderItemForeignId = ?和bookingwin0_.OrderItemTypeId ='1'
任何人都可以向我解释我在这里所犯的错误。也许它很明显,但我已经挣扎了几个小时,并在我的耐心结束:)
感谢您回到这一个。我现在可以理解这是如何引起你的解释,并决定作出调整,以阻止这种情况发生。 – 2013-05-18 14:24:19
伟大的在这里。希望NHibernate的最佳...学习有点具有挑战性,但是一旦你知道如何去管理它,那就太好了。 – 2013-05-18 14:29:00