NHibernateは、LinqまたはCriteria API経由ではなく、session.Load()経由でプロキシを作成します

StackOverflow https://stackoverflow.com/questions/1643905

質問

現在のプロジェクトに奇妙な問題があります。クエリの遅延読み込みは機能しません。リストを照会すると、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; }
}

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 は初期化され(2番目の選択クエリを起動)、返されたオブジェクトはプロキシではありません。

デフォルトの動作ですか?何が間違っているのですか?

マッピングは次のとおりです。

<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の遅延読み込みを防ぐことができるものがたくさんあるからです。

  1. Query vs. session.Load: session.Load()を介してアイテムを取得すると、プロキシが取得されます。ただし、任意のプロパティにアクセスするとすぐに、 Url と言うと、遅延読み込みをサポートしないすべての関連付けを含むオブジェクトがフェッチされます。

  2. property-ref:遅延読み込みはオブジェクトIDに対してのみ機能します。プロパティの関連付けがターゲットエンティティの別の列を介して解決されると、NHはそれを積極的にフェッチします。 これは不可能ではなく、実装されていないだけではありません:バグ

  3. not-found =&quot; ignore&quot; は、無効な外部キーを許可します。つまり、参照されたエンティティが見つからない場合、NHはプロパティを初期化しますヌル。 NHは、遅延読み込みのプロパティアクセスをインターセプトせず、代わりにオブジェクトプロキシを割り当てます。 not-found =&quot; ignore&quot; を使用すると、プロパティをnullに設定するか、指定された(場合によっては無効な)外部キーのプロキシに設定するかを決定できません。 これは、プロパティアクセスをインターセプトすることで解決できる可能性があります。

  4. not-found =&quot; ignore&quot; および property-ref を無効にすると、スキーマのエクスポートにより、循環参照を強制する制約が生成されます。良くない!正しいマッピングは、制約された1対1の関係になります。この場合、 HippoAccountSync のキーにはジェネレーター foreign が必要です。

リソース

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top