使用 property-ref 映射到非键字段时,延迟加载不适用于多对一关系

发布于 2024-07-14 05:56:31 字数 1322 浏览 6 评论 0原文

我有一个旧数据库,正在使用 NHibernate 进行映射。 关注的对象是帐户和通知对象列表。 对象看起来像:

public class Notification
{
    public virtual int Id { get; set; }
    public virtual DateTime BatchDate { get; set; }
    /* other properties */

    public virtual Account Account { get; set; }
}

public class Account 
{
    public virtual int Id { get; set; }
    public virtual string AccountNumber { get; set; }
    /* other properties */ 
}

映射文件看起来像:

<class name="Account" table="Account" dynamic-update="true">
<id name="Id" column="AccountID">
    <generator class="native" />
</id>
<property name="AccountNumber" length="15" not-null="true" />
    <!-- other properties -->
</class>

<class name="Notification" table="Notification">
    <id name="Id" column="Id">
        <generator class="native" />
    </id>
    <!-- other properties -->
    <many-to-one name="Account" class="Account" property-ref="AccountNumber" lazy="proxy">
        <column name="AcctNum" />
    </many-to-one>

但是,当我创建一个标准时,例如

return session.CreateCriteria(typeof(Notification)).List<Notification>();

我收到一个 Select N+1 情况,其中每个帐户都会被加载,即使该帐户从未被引用。 当多对一映射为惰性代理时,为什么所有帐户都会被加载?

I have a legacy database that I am mapping using NHibernate. The objects of concern are an Account and a list of Notification objects. The objects look like:

public class Notification
{
    public virtual int Id { get; set; }
    public virtual DateTime BatchDate { get; set; }
    /* other properties */

    public virtual Account Account { get; set; }
}

public class Account 
{
    public virtual int Id { get; set; }
    public virtual string AccountNumber { get; set; }
    /* other properties */ 
}

The mapping files look like:

<class name="Account" table="Account" dynamic-update="true">
<id name="Id" column="AccountID">
    <generator class="native" />
</id>
<property name="AccountNumber" length="15" not-null="true" />
    <!-- other properties -->
</class>

<class name="Notification" table="Notification">
    <id name="Id" column="Id">
        <generator class="native" />
    </id>
    <!-- other properties -->
    <many-to-one name="Account" class="Account" property-ref="AccountNumber" lazy="proxy">
        <column name="AcctNum" />
    </many-to-one>

However, when I create a criteria such as

return session.CreateCriteria(typeof(Notification)).List<Notification>();

I am getting a Select N+1 case where each account is loaded even though the Account is never referenced. Why are all of the accounts getting loaded when the many-to-one is mapped as a lazy proxy?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深陷 2024-07-21 05:56:31

该问题是由 property-ref 属性引起的。 延迟加载仅在多对一引用使用其他对象的主键时才有效,因为 NHibernate 假定存在外键约束来强制执行此类值的有效性。 对于非主键(由 property-ref 指示),NHibernate 不会做出此假设,因此不会假设相关对象必须存在。 由于它不想为不存在的对象创建代理(即应该为 null 而不是代理),因此它急切地获取远程对象。 当指定 not-found="ignore" 时,也存在同样的问题,因为这表明外键关系未强制执行,并可能导致空引用。

另请参阅:

The issue is caused by the property-ref attribute. Lazy loading only works when the many-to-one reference is using the other object's primary key since NHibernate assumes there's a foreign key constraint enforcing the validity of such a value. With a non-primary key (indicated by the property-ref), NHibernate does not make this assumption and thus does not assume the related object must exist. Since it does not want to create a proxy for an object that does not exist (i.e. should be null instead of a proxy), it eagerly fetches the remote object. This same issue exists when not-found="ignore" is specified since this indicates that the foreign key relationship is not enforced and may result in a null reference.

See also:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文