2

我々は、Fluent NHibernate 1.3.0.727とNHibernate 3.3.0.4000を使用して、プロパティをデータベースのカラムにマッピングしています。ここに私たちのクラスマップの1の簡略サンプルは次のとおりです。この場合、NHibernateのプロパティ代理オーバーヘッドをどのように減らすことができますか?

public class TankMap : ClassMap<Tank> 
    { 
     public TankMap() 
     { 
      Id(o => o.Id); 
      Map(o => o.TankSystem); 
     } 
    } 

TankSystemプロパティは、文字列です。

私たちのアプリケーションの一部では、マッピングされたプロパティ(TankSystemなど)に何度もアクセスすることを含む多くの計算があります。アプリケーションをプロファイリングするときは、これらのプロパティにアクセスするだけでかなりの時間がかかります。なぜなら、アクセスするたびにNHibernate.Proxy.DefaultLazyInitializer.Interceptメソッドを実行する必要があるからです。

できるだけ早く計算を行う必要があり、このプロキシオーバーヘッドを避けたいと考えています。 1つのアプローチは、必要なプロパティ(たとえばTankSystem)を配列にコピーし、この情報にアクセスするたびに配列を使用することですが、これはオブジェクト指向のアプローチではありません。

更新:

私たちは、例えば、Not.LazyLoadを使用して私たちのプロパティをマッピングしようとしている:

Map(o => o.TankSystem).Not.LazyLoad(); 

しかし、これは、このプロパティは、実際にプロキシされているかどうかに影響を持っていないようです。

このプロキシオーバーヘッドを避ける/減らすオプションはありますか?

+0

NHibernate 3.xはCastle DynamicProxyを使用していません。そういうわけで、この質問は間違っていると思います。 –

答えて

1

はい!レスキューのための.Not.LazyLoad()

public TankMap() 
    { 
     Id(o => o.Id); 
     Map(o => o.TankSystem).Not.LazyLoad(); 
    } 

は、私はそれについて良いと短い説明を見つけた:

あなたはNot.LazyLoad()が何を意味するのか不思議に思うかもしれません。デフォルトでは、Fluent NHibernateは遅延ロードを使用するためのマッピングを定義します。しかし、これは、エンティティのすべてのプロパティが仮想(プロキシ)でなければならないことを意味します。オブジェクト上で仮想的特性を有する避けるために

source

+0

私はこのアプローチを試みましたが、違いは見られませんでした.TankSystemプロパティはまだプロキシになっていました。私たちは古いバージョンのFluentNHibernate(1.2.0.712)を使用していますので、この変更は新しいバージョンでは機能するかもしれません - 私は最新バージョンにアップグレードし、役立つかどうか確認します! –

+0

残念ながら、このアプローチは私たちのために何もしないようです。 dotTraceを使用したプロファイリングでは、すべてのNo.LazyLoadプロパティの呼び出しがNHibernate.Proxy.DefaultLazyInitializer.Interceptメソッドに引き続き通過することが表示されます。 @ GeoffHardy。 –

+0

しかし、それはあなたがプロキシを取得するとは言いません!更新すると**アップデート**と書かれています。あなたのアップデートによって全ての答えが馬鹿に見えるからです。 – gdoron

0

一つの方法は次のとおりです。

public TankMap() 
{ 
     Id(o => o.Id); 
     this.Not.LazyLoad(); 
     Map(o => o.TankSystem); 
} 

この方法には、プロパティプロキシ魔法はありません。

+0

もし私が間違っていないなら、それは**すべての**プロパティがlazyloadedではなくなります。これは巨大なパフォーマンスヒットとなります! – gdoron

+0

はい、そのようになり、プロパティのどれも仮想である必要はありません。一部のプロパティを遅延ロードする必要がある場合は、パフォーマンスが低下します。 – eulerfx

+0

これを2回何度も行うと、1行のクエリの後にメモリ内のDB全体が終了する可能性があります。だから私は 'class'レベルの代わりに' property'レベルで '.Not.LazyLoad()'を設定する方が好きです。 – gdoron

1

あなたのマッピングでは、実際には.Not.LazyLoad()を使用することに注意し、必要に応じて質問に熱心に負荷をかけます。 lazyloadフェッチ戦略が正しく構成されていないと、問題が発生する可能性があります。 NHProfのようなツールですべてのクエリをチェックするのが最善です。

のLINQ:

var tanks = _session.Linq<Tank>() 
       .Fetch(x=>x.TankSystem) 
       .ToList(); 

QueryOver(マイ県): VARタンク= _session.QueryOver() .Fetch(X => x.TankSystem).Eager 。リスト();

TankSystem tankSystemAlias = null; 
var tanks = _session.QueryOver<Tank>() 
       .JoinAlias(x=>x.TankSystem,() => tankSystemAlias, JoinType.InnerJoin) // or JoinType.LeftOuterJoin 
       .List() 
関連する問題