2

タイトルのとおり、ReferencesAny 関連付けを持つオブジェクトがありますが、参照先のオブジェクトが削除されている可能性があります。これが発生した場合、現在、不足しているオブジェクトはプロキシで初期化され、アクセスすると ObjectNotFound がスローされます。他のプロパティで not-found を「無視」に設定するのと同様の方法で、代わりに null を返すようにしたいと考えています。Session.Get と Session.Load の使用の違いは理解していますが、これは LINQ クエリの結果として発生しています。

それで、私の質問は、「any」関連付けの不足しているオブジェクトに対して null を返すように指定するにはどうすればよいですか?

4

1 に答える 1

6

私はxml構成を使用していますが、私のヒントがとにかく役立つと思います... NHibernate は、これらの不完全なマッピングに対して、デフォルトで「例外」に設定されている属性not-foundを提供します。この例では、多対 1マッピングを参照していますが、1対多にも使用できます。

<many-to-one name="MyReferencedObject" not-found="exception" />

ただし、無視するように変更できます

<many-to-one name="MyReferencedObject" not-found="ignore" />

その場合、結果は NULL になります。(ただし、注意してください。NHibernate は常に SQL select ステートメントを実行します。そのような「NULL」値はキャッシュされないためです)


EDIT : 以下のコメントに基づいて、私の提案は<any>マッピングでは機能しないと言わざるを得ません。申し訳ありませんが、もっと注意深く読む必要があります...しかし、それを修正する方法を提案させてください。


イベントリスナーを導入できます。詳細はこちらhttp://nhibernate.info/doc/nh/en/index.html#objectstate-events

一言で言えば解決策:

イベントリスナーを導入する

public class PostLoadListener 
           : NHibernate.Event.Default.DefaultPostLoadEventListener
{ ... }

それを「session-factory」構成に挿入します。

<event type="post-load">
    <listener class="MyLib.PostLoadListener, MyLib"/>
</event>

トリックは、オーバーライドされたメソッドOnPostLoad内にあります

public override void OnPostLoad(PostLoadEvent @event)
{
    base.OnPostLoad(@event);

    // the entity with <any> mapping 
    ConvertToNull(@event.Entity as MyAuditEntity); 
}

protected virtual void ConvertToNull(MyAuditEntity item)
{
    if (item == null)
    {
        return;
    }
    try
    {
        // access some property to check that reference is not a PROXY
        var id = item.AnyEntity.ID;
    }
    catch
    {
        // replace proxy with null
        item.AnyEntity = null; 
    }
}

もちろん、これは not-found="ignore" のような答えではありません。しかし、この回避策はその仕事をします。

于 2012-10-30T18:58:09.397 に答える