环境:NHibernate(3.3.3.4001)、FluentNHibernate(1.4.0.0) 以下是 FluentNHibernate 映射:
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x.Id);
Map(x => x.Name).Not.Nullable();
HasMany(x => x.Orders)
.KeyColumn("CustomerId")
.Cascade.All()
.LazyLoad();
HasMany(x => x.Cards)
.KeyColumn("CustomerId")
.Cascade.All()
.LazyLoad();
}
}
public class OrderMap:ClassMap<Order>
{
public OrderMap()
{
Id(x => x.Id);
Map(x => x.OrderTime).Not.Nullable();
References<Customer>(x => x.OrderOwner)
.LazyLoad().Column("CustomerId");
}
}
public class CardMap:ClassMap<Card>
{
public CardMap()
{
Id(x => x.Id);
Map(x => x.CardCode).Not.Nullable();
References<Customer>(x => x.CardOwner)
.LazyLoad().Column("CustomerId");
}
}
实体:
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Order> Orders { get; set; }
public virtual IList<Card> Cards { get; set; }
}
public class Order
{
public virtual int Id { get; set; }
public virtual DateTime OrderTime { get; set; }
public virtual Customer OrderOwner { get; set; }
}
public class Card
{
public virtual int Id { get; set; }
public virtual string CardCode { get; set; }
public virtual Customer CardOwner { get; set; }
}
现在在我的数据库中, 客户表
Id Name
1 AAA
2 BBB
订单表
Id OrderTime CustomerId
1 2014-04-20 00:48:52.110 1
2 2014-04-20 00:48:52.110 2
3 2014-04-20 00:49:01.403 1
4 2014-04-20 00:49:01.403 1
卡片桌
Id CardCode CustomerId
1 111 1
2 111 2
5 222 1
6 333 1
当我使用Criteria和FetchMode.Join来获取惰性数据时,结果将包含属于客户的重复订单和卡。 例如Customer Id = 1,它包含9(3×3)个Order对象和9(3×3)个Card对象。
ISession session = FluentlyNHManager.OpenSession();
ICriteria customerCriteria = session.CreateCriteria<Customer>()
.SetFetchMode("Orders", FetchMode.Join)
.SetFetchMode("Cards", FetchMode.Join)
.SetResultTransformer(Transformers.DistinctRootEntity);
IList<Customer> customerList = customerCriteria.List<Customer>();
但是如果我使用HQL来获取数据,那就是正确的。客户 ID = 1 包含 3 个订单对象和 3 个卡对象。
ISession session = FluentlyNHManager.OpenSession();
ICriteria customerCriteria = session.CreateCriteria<Customer>(@"from Customer c left join fetch
Orders o left join fetch Cards c");
IList<Customer> customerList = customerCriteria.List<Customer>();
我可以编写什么代码来解决有关 Criteria 的问题?为什么结果错误?
正如这篇有趣的读物中提到的:Ayende - 使用 NHibernate 高效地提前加载实体关联:
似乎经常出现的事情之一是人们希望急切地加载一个实体及其所有关联。当关联是多对一时(即每个根实体只有一个),这很容易做到。例如,所有者、站点等。
...
当您尝试对多个集合关联执行相同操作时,问题就会出现。 NHibernate 允许您这样做,但结果可能不是您最初期望的......
有一些常用的方法,请查看:
详细操作方法可以在这里找到:
注意:如果您已获取 child 和其他 child 并且... 不同的根转换 将无法完成这项工作,因为它只针对一个根执行此操作...
我的首选方法是:创建仅连接
many-to-one
引用的简单查询。使用 batch-size
功能让集合延迟加载(21.1.5.使用批量获取)
xml:
// class
<class name="ParentEntity" batch-size="25" lazy="true">
// collection
<bag name="Children" lazy="true" batch-size="25"
流利:
.BatchSize(25)