在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