我当前的项目中有一个奇怪的问题。查询的延迟加载不起作用。当我查询列表时,nhibernate 分别获取所有关联。
我提取了它的一小部分并将其放入单独的解决方案中。基本上我现在得到的是一个 Account-Table 和一个 AccountSync-Table。两者都有一个 ID 和一个 URL,而 ID 只是一个 db-guid。
我的类(class)是:
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];
... 属性(property)
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>
最佳答案
经过更多的研究,我找到了答案。答案,因为在 NHibernate 中有很多东西可以防止延迟加载。
session.Load()
获取项目时你得到一个代理。但是只要您访问 任何 属性,可以说 Url
,该对象被获取,包括所有不支持延迟加载的关联。 not-found="ignore"
它无法决定是否应将属性设置为 null 或为给定的可能无效的外键设置代理。这可能可以通过拦截属性访问来解决。 not-found="ignore"
和 property-ref
模式导出将生成强制循环引用的约束。不好!正确的映射将是受约束的一对一关系,其中 HippoAccountSync
的键是必须有发电机foreign
. 资源
关于NHibernate 通过 session.Load() 创建代理,而不是通过 Linq 或 Criteria API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1643905/