【发布时间】:2011-11-24 07:57:43
【问题描述】:
在使用 POCO 实体玩弄 Entity Framework 和 NHibernate 时,我做了以下观察,我觉得这有点不寻常:
我有两个 POCO 实体,一个“订单”和一个“产品”。两者之间存在多对多的关系。当我将产品添加到订单时,我使用“FixUp”方法来确保关系的另一方也被更新,即 - “订单”的产品集合也被更新。
我的订单 POCO 实体具有以下方法来执行“修复”:
private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.NewItems != null)
{
foreach(Product p in e.NewItems)
{
p.Order.Add(this);
}
}
}
在使用 EFProf 和 NHProf 分析此场景时,我观察到实体框架生成的 SQL 语句比 NHibernate 多,其原因似乎是这一行:
p.Order.Add(this);
使用实体框架,上面的行会导致在数据库上执行选择以返回产品“p”的所有订单。我不希望发生这种情况,因为我正在使用延迟加载并且实际上并不想访问产品“订单”集合。我只想给它添加一个订单。
使用 NHibernate 不会尝试加载订单的产品集合,除非我明确尝试访问它。例如,如果我说:
foreach(Order o in product.Orders)
{
Console.WriteLine(o.Id);
}
所以最终我的问题是,为什么 Entity Framework 会生成额外的 SQL 语句?我不知道的两个框架的延迟加载实现是否有区别?
***编辑为原始 一旦在集合上调用任何类型的方法,Entity Framework 似乎不会以惰性方式运行。任何添加或计数的尝试(或可能对集合的任何其他操作)都会导致该集合被加载到内存中。
有趣的是我的 NHibernate 映射(它是一个“产品包 - 如下所示),尽管我的映射被配置为只是懒惰的,但它的行为似乎是一种“超懒惰”的方式:
<bag name="Products" cascade ="all" table="OrderProduct" mutable="true" lazy="true">
我可以在不加载到内存的情况下“添加”到集合中。我认为调用 'Count' 会导致订单被加载,除非我将其配置为 'extra-lazy'。
谁能评论这是否正确?
【问题讨论】:
标签: nhibernate entity-framework-4 lazy-loading