2

私はこの状況にあります:

Nhibernateを使用して、SQLの大きなテーブルにマップされるエンティティ' User 'をマップしています。パフォーマンス上の理由から、プロパティのセットが少なく、hbmにマップされない軽量エンティティ'LightweightUser'を作成しましたファイルなど、「 LightweightUser」エンティティをワイヤリングするためにNhibernateProjectionテクニックを使用しています。両方のエンティティは、Idプロパティを含む単純なクラス「Entity」から派生しています。

上記の実装は正常に機能し、SQLクエリは小さく==高速です。

しかし、私のNhibernate SessionFactoryには、NhibernateIntercerptorも注入しました。インターセプターのOnLoadメソッドは、NHibernate Daoから「User」エンティティを取得しているときに呼び出されますが、NHibernate Daoから「LightweightUser」エンティティを取得すると、インターセプターはトリガーされません(OnLoadメソッド)。

これはおそらく、NHibernateSessionFactoryが私の「LightweightUser」エンティティを認識していないという事実に関連しています。私の「軽量」エンティティの存在をSessionfactory/Interceptorに通知する方法はありますか?または、プロジェクションをインターセプターに配線する他のテクニックはありますか?はい、Lightweightエンティティの「hbm」ファイルを複製することもできますが、それは悪い習慣のようです。

    [TestFixture]
    public class InterceptorTest : NhibernateSessionHelper
    {
    [Test]
    public void GetEntiy()
    {
        //ok trigger OnLoad in the Interceptor
        var user = GetSession().Get<User>(1);
        Assert.IsNotNull(user);
    }

    [Test]
    public void GetProjection()
    {
        var crit = GetSession().CreateCriteria<User>();
        crit.Add(Restrictions.Eq("Id", 5));
        crit.SetProjection(Projections.ProjectionList()
                                      .Add(Projections.Property("Id"), "Id")
                                      .Add(Projections.Property("Username"), "UserName"));

        crit.SetResultTransformer(Transformers.AliasToBean(typeof(LightweightUser)));

        //does not trigger the Interceptor
        var result = crit.List<LightweightUser>();

        Assert.IsNotNull(result.First());

    }
} 


    //Wire the Sessionfactory with Interceptor
    private static ISessionFactory CreateSessionFactory()
    {
        return new Configuration()
        .CurrentSessionContext<ThreadStaticSessionContext>()
        .SetInterceptor(new MyInterceptor())
            .Configure().BuildSessionFactory();
    }


 public class MyInterceptor: IInterceptor
{
    public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
    {
        //do stuff

        var s = entity;
        return base.OnLoad(entity, id, state, propertyNames, types);
    }

前もって感謝します

4

1 に答える 1

2

Interceptor のメソッド OnLoad は、PreLoadEvent の処理でのみ呼び出されます。これは、エンティティがデータベースからロードされるとき、またはエンティティがキャッシュからアセンブルされるときの 2 つのケースで発生します。あなたのようなプロジェクションで作成されたオブジェクトは、エンティティとは見なされません。

エンティティと LightweightUser のタプルに同じコードを適用する場合は、のインスタンスを含むカスタム IResultTransformer を実装できます。

Transformers.AliasToBean(typeof(LightweightUser))

元のトランスフォーマーメソッドを呼び出した後、ロジックを適用します

//do stuff

インターセプターについて詳しく知りたい場合は、ここから始まる私のブログ エントリのリストを読むことをお勧めします

于 2013-07-01T09:40:36.043 に答える