2011-11-09 17 views
0

NHibernateの実装とLazy Loadingを使用したプロジェクトがあります。このプロジェクトには、PersonとPersonIdentityという2つのクラスがあります。それら2つの間の関係は集約であり、1人のPersonIdentityを有することを意味する。NHibernateのクエリと最適なパフォーマンスの最適化方法

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

<class name="Person" table="Person_Person" > 

    <id name="Id" type="Int64" unsaved-value="0"> 
     <generator class="native" /> 
    </id> 

    <version name="Version" /> 

    <property name="Name" column="Name" 
       type="String(255)" access="property" not-null="false" /> 

    <one-to-one name="Identity" property-ref="Person" 
     class="Domain.Entities.PersonIdentity,Domain.Entities" cascade="delete" fetch="select" /> 

</class> 

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

<id name="Id" type="Int64" unsaved-value="0" > 
     <generator class="native" /> 
    </id> 

    <property name="FirstName" column="FirstName" type="String(255)" access="property" not-null="false" /> 

    <property name="LastName" column="LastName" type="String(255)" access="property" not-null="false" /> 

    <many-to-one name="Person" column="Person_id_fk" uniqe="true" class="Domain.Entities.Person,Domain.Entities" 
     outer-join="auto" fetch="select" access="property" not-null="true" /> 

    </class> 

私の問題は、パフォーマンスです。私はこのような人だけにクエリを実行する場合:

SELECT * FROM Person_Identiyt WHERE Id = 1; 
SELECT * FROM Person_Identiyt WHERE Id = 2; 
SELECT * FROM Person_Identiyt WHERE Id = 3; 
... 

var q = SessionInstance.Query<Person>(); 
IList list = q.ToList<Person>(); 

私だけ

SELECT * FROM Person_Person 

を実行それに加えて、データベース内の一人当たり、このようなクエリを実行期待します

そして怠け者のアプローチによると、それは良くありません。 PersonIdentityは呼び出すまでロードしないでください。 最初に読み込むためにPersonIdentityを持たないPersonだけをロードするにはどうすればよいですか?

+0

人物のアイデンティティは常にあります – Ehsan

答えて

1

プロキシ(遅延読み込み)は、オプションの1対1のもので使用されることはありません。

プロキシは常に何かがあることを意味しますが、1対1の場合、他のテーブルに行が存在しない可能性があります。また、プロキシがownerプロパティから自分自身を削除すること(およびnullに設定すること)ができないため、プロキシは使用できません。

あなたのDBが常にアイデンティティ(個人からアイデンティティへの外部キー)があることを確認したら、constrained="true"を一対一に追加することができ、NHibernateはプロキシを使用します。

回避策:

  • 常に選択のn + 1つの問題を回避するために(fetch="join"付き)のアイデンティティをロードします。 (注:正しく覚えていれば、まだn + 1の場合はNHibernate Jiraを参照してください)
  • リファレンスをコレクションとしてマップし、Personクラスにcollection.SingleOrDefault()を呼び出すプロパティを提供してください。そうすれば、遅延ロードを使用できます。
+0

Person hbmのPersonIdentityに対して一対一関係に 'constrained =" true "'を追加しました。しかし、次の2つの問題があります。* insert *および* delete * Personがこのメッセージによってエラーが存在する場合:not-nullプロパティは、nullまたは一時値Domain.Entities.PersonIdentity.Personを参照します。しかし、更新は本当です。どうして? – Ehsan

+0

この変更により、Domain.Entities.PersonIdentity.Personが一時的なのはなぜですか?しかし、 'constrained =" true "'を追加する前に、それは正しいのですか? Personの 'GetByID(x)'もそれぞれの場合に依然として存在する。さらに、 'Select * from Person_Person'は' Select * from Person_identity where ID = x'の第2のクエリを実行した。どうして? – Ehsan

+0

@ehsanzeynali 'PersonIdentity'とエンティティの保存と読み込みに使用するコードのマッピングを投稿してください。 – cremor

関連する問題