在 NHibernate 中有一个看似奇怪的 N+1 选择问题。我正在执行一个查询,我要求一堆实体,其中一个链接属性为空。在这种情况下,我实际上不需要 NHibernate 返回链接属性,因为它只是为了选择正确的数据。
第一个实体是预订窗口
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>();
所以第一个查询会像这样发送到数据库(选择了订单项列,这有点烦人,但真正的问题在一分钟后出现)
选择 this_.Id 作为 Id2_1_, this_.Price 作为 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_ FROM Customer.BookingWindows this_ 左外连接 Payment.OrderItem bookingwin1_ on this_.Id=bookingwin1_.OrderItemForeignId 和 bookingwin1_.OrderItemTypeId='1' 在哪里 this_.RoomId = ?并且 bookingwin1_.Id 为空
但是对于每个返回的预订窗口,即使我没有要求或不需要它,链接的订单项目也会有一个额外的选择。这发生在查询方法中,因此我不会手动对返回的预订窗口进行任何迭代。
选择 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_。和 bookingwin0_.OrderItemTypeId='1'
谁能向我解释我在这里犯的错误。也许它很明显,但我已经挣扎了几个小时,在我的耐心结束时:)