Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NHibernate通过session.Load()创建代理,但不是通过Linq或Criteria API_Nhibernate_Lazy Loading_Criteria - Fatal编程技术网

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

NHibernate通过session.Load()创建代理,但不是通过Linq或Criteria API,nhibernate,lazy-loading,criteria,Nhibernate,Lazy Loading,Criteria,我目前的项目有一个奇怪的问题。查询的延迟加载不起作用。当我查询列表时,nhibernate分别获取所有关联 我提取了它的一小部分,并将其放入一个单独的解决方案中。基本上我现在得到的是一个Account表和一个AccountSync表。两者都有一个ID和一个URL,而ID只是一个db guid 我的课程是: public class HippoAccount { public virtual Guid Id { get; set; } public virtual string U

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

我提取了它的一小部分,并将其放入一个单独的解决方案中。基本上我现在得到的是一个Account表和一个AccountSync表。两者都有一个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"))
。。。属性
Sync
被初始化(触发第二个select查询),并且返回的对象不是代理

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

映射为:

<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>

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

  • 查询vs.session.Load:通过
    session.Load()
    获取项目时,您会得到一个代理。但是,只要您访问任何属性,比如
    Url
    ,就会获取对象,包括所有不支持延迟加载的关联

  • 属性引用:延迟加载仅对对象id有效。当通过目标实体中的不同列解析属性关联时,NH会急切地获取它。并不是说这不可能,只是没有实施:

  • not found=“ignore”允许无效的外键,也就是说,如果未找到引用的实体,NH将使用null初始化属性。NH不会拦截延迟加载的属性访问,而是分配一个对象代理。使用
    not found=“ignore”
    时,它无法决定是将属性设置为null还是为给定的可能无效的外键设置代理。这可能通过拦截属性访问来解决

  • 禁用
    not found=“ignore”
    property ref
    时,架构导出将生成强制循环引用的约束。不好的!然后,正确的映射将是受约束的一对一关系,其中
    HippoAccountSync
    的键必须有一个生成器
    foreign

  • 资源


    不确定是否完全相关,但not found=“ignore”存在问题:您是对的。另一个问题是属性ref-它还禁用延迟加载。当然,使用session.Load(),您可以安全地访问代理的Id属性,而无需访问数据库,因为您为代理提供了要开始的Id。指向属性ref的链接错误不再存在,404错误。你知道这方面的进展吗?
    <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>