NHibernate通过session.Load()创建代理,但不通过Linq或Criteria API创建代理

Lar*_*sen 10 nhibernate lazy-loading criteria

我目前的项目有一个奇怪的问题.延迟加载查询不起作用.当我查询列表时,nhibernate分别获取所有关联.

我提取了它的一小部分并将其放入一个单独的解决方案中.基本上我现在拥有的是一个Account-Table和一个AccountSync-Table.两者都有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; }
}
Run Code Online (Sandbox Code Playgroud)

当我现在通过它的guid加载一个对象时:

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

...它返回false并且帐户本身是代理.

但是当通过条件API加载列表时:

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

...属性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>
Run Code Online (Sandbox Code Playgroud)

Lar*_*sen 11

经过相当多的研究,我找到了答案.答案,因为有很多东西可以阻止NHibernate中的延迟加载.

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

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

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

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

资源