2009-10-29 67 views
9

我在当前项目中有一个奇怪的问题。延迟加载查询不起作用。当我查询列表时,nhibernate会分别提取所有关联。NHibernate通过session.Load()创建代理,但不通过Linq或Criteria API

我提取了它的小部分,并将其放入单独的解决方案。基本上我现在得到的是帐户表和帐户同步表。两者都有一个ID和一个URL,而ID只是一个db-guid。

我的类别是:

public class HippoAccount 
{ 
    public virtual Guid Id { get; set; } 
    public virtual string Url { get; set; } 
    public virtual HippoAccountSync Sync { get; set; } 
} 

public class HippoAccountSync 
{ 
    public virtual Guid Id { get; set; } 

    public virtual string Url { get; set; } 
    public virtual HippoAccount Account { get; set; } 
} 

当我现在加载对象通过它的GUID:

var account = session.Load<HippoAccount>(accountId); 
Console.WriteLine(NHibernateUtil.IsPropertyInitialized(account, "Sync")) 

...返回false和账户本身就是一个代理。

但通过标准API时加载列表:

var account = (HippoAccount)session 
    .CreateCriteria(typeof (HippoAccount)) 
    .Add(Restrictions.Eq("Id", accountId)) 
    .List()[0]; 

...财产Sync被初始化(烧成第二选择查询),并且返回的对象不是代理。

这是默认行为吗?我错了什么?

的映射是:

<class name="HippoAccount" table="AllAccounts"> 
    <id name="Id" type="guid"> 
    <generator class="guid"/> 
    </id> 
    <property name="Url" /> 

    <many-to-one 
      class="HippoAccountSync" 
      name="Sync" 
      not-found="ignore" 
      property-ref="Url"> 
    <column name="url" /> 
    </many-to-one> 
</class> 

<class name="HippoAccountSync" 
     mutable="false" 
     table="Accounts"> 

    <id name="Id" type="guid"> 
    <generator class="guid"/> 
    </id> 

    <property name="Url"> 
    <column name="serviceUri" /> 
    </property> 

    <many-to-one class="HippoAccount" 
       name="Account" 
       property-ref="Url" 
       not-found="ignore"> 

    <column name="serviceUri" /> 
    </many-to-one> 

</class> 
+0

不知道这是否是完全相关的,但也有问题,与未找到= “忽略”: http://nhjira.koah.net/browse/NH-1001 http://guildsocial.web703 .discountasp.net/dasblogce/CommentView,guid,ba00b19d-bd60-442b-b2e7-935277a9f1eb.aspx – 2009-10-29 18:11:49

+0

你说得对。另一个问题是property-ref - 它也会禁用延迟加载。 http://maonet.wordpress.com/2007/12/05/lazy-load-conflicts-with-property-ref-in-many-to-one-mapping/ – 2009-10-30 12:01:42

回答

10

相当一些调查研究后,我找到了答案。答案,因为有很多事情可以防止在NHibernate中延迟加载。

  1. 查询与session.Load:当通过session.Load()获取一个项目你会得到一个代理。但只要你访问任何属性,让我们说Url,该对象被提取,包括所有它不支持延迟加载的关联。

  2. property-ref:延迟加载仅适用于对象ID。当通过目标实体中的不同列解决属性关联时,NH会热切地获取它。 不,这是不可能的,它只是没有实现:Bug

  3. 未找到=“忽略”允许无效外键,也就是说,如果引用的实体没有找到NH将用null初始化属性。 NH不会拦截用于延迟加载的属性访问,而是指定对象代理。与not-found="ignore"它不能决定该属性是否应该设置为null或给定的,可能无效的外键的代理。 这可能可以通过拦截属性访问来解决。

  4. 当禁用not-found="ignore"property-ref架构出口会产生强制循环引用约束。不好!正确的映射将是一个约束的一对一关系,其中HippoAccountSync的密钥必须具有生成器foreign

资源

+0

使用session.Load(),您可以,当然,可以安全地访问代理的Id属性,而不必访问数据库,因为您已将代理ID设置为开头。 – Jay 2010-09-14 14:13:39

+0

链接到property-ref bug不再存在,404错误。有关这一进展的任何想法? – shanabus 2011-04-25 21:38:12