在我的模型中,我有类似的东西:
Order
有很多Payment
Payment
有零个或一个PaymentMethod
PaymentMethod
是抽象的,有一个Payment
(循环引用),不能延迟加载。
当我进行如下查询时:
var orders = session.Query<Order>().FetchMany(x => x.Payments)
.ThenFetch(x => x.PaymentMethod).ToList();
NHibernate执行一个语句,就像预期连接所有三个表一样。然后它为每个Payment
执行一个语句。
当我删除循环引用时,一切正常,所以我猜它与HasOne关系有关。
这会让表现非常糟糕。为什么NHibernate会执行这些额外的查询以及如何修复映射,因此只会执行一个sql语句?
以下是我的映射:
public class Order
{
public virtual int Id { get; set; }
public virtual string Text { get; set; }
public virtual ICollection<Payment> Payments { get; set; }
}
public class Payment
{
public virtual int Id { get; set; }
public virtual Order Order { get; set; }
public virtual PaymentMethod PaymentMethod { get; set; }
}
public class PaymentMethod
{
public virtual int Id { get; set; }
public virtual Payment Payment { get; set; }
}
public class CreditcardPaymentMethod : PaymentMethod
{
}
public class OrderMap : ClassMap<Order>
{
public OrderMap()
{
Id(x => x.Id).GeneratedBy.Native();
Map(x => x.Text);
HasMany(x => x.Payments).KeyColumn("OrderId").Not.KeyNullable().Inverse().Cascade.All();
}
}
public class PaymentMap : ClassMap<Payment>
{
public PaymentMap()
{
Id(x => x.Id).GeneratedBy.Native();
References(x => x.Order).Column("OrderId").Not.Nullable().Cascade.SaveUpdate();
References(x => x.PaymentMethod).Column("PaymentMethodId").Not.LazyLoad().Not.Nullable().Cascade.All();
}
}
public class PaymentMethodMap : ClassMap<PaymentMethod>
{
public PaymentMethodMap()
{
Id(x => x.Id).GeneratedBy.Native();
DiscriminateSubClassesOnColumn("Discriminator").Not.Nullable();
HasOne(x => x.Payment).PropertyRef(x => x.PaymentMethod).ForeignKey("PaymentMethodId").Cascade.All();
}
}
public class CreditcardPaymentMethodMap : SubclassMap<CreditcardPaymentMethod>
{
public CreditcardPaymentMethodMap()
{
DiscriminatorValue("Creditcard");
}
}