2009-08-07 5 views
24

私はNHibernateを使用するプロジェクトに取り組んでいます。 私はセッションを開いたままにしません。オブジェクトを取得または保存する必要があるときは、セッションを開き、必要なものを実行してからセッションを閉じます。だから私はいつもセッションから切り離されたオブジェクトを使って作業しています。セッションが切り離されたときにNHibernateで変更されたプロパティのみを更新する最良の方法は何ですか?

たとえば、データベースからオブジェクトを取得する必要がある場合、セッションを開き、session.Get()を呼び出してセッションを閉じます。次に、私はデタッチされたオブジェクトのいくつかのプロパティを更新します。変更をデータベースに保存する必要があるときは、セッションを開くメソッドを呼び出し、session.Update(myObject)を呼び出してセッションを閉じます。

しかし、そうすると、NHibernateは変更されていなくても、マップしたすべてのフィールドを更新するsqlを生成します。私の提案は、オブジェクトがセッションから切り離されたときで、NHibernateは変更が行われたことを追跡できませんでした。 セッションから切り離されたオブジェクトに対して変更されたプロパティのみを更新する場合は、どのような方法を使用しますか?切り離されたオブジェクトの変更をどのように追跡しますか?

おかげ

答えて

17

質問です:なぜあなたはこれをしたいですか?変更された列のみを更新すれば、それほど最適化されないと思います。

データベースにトリガーがありますか?マッピングで

  • 使用select-before-update="true"dynamic-update="true":もしそうなら

    は、次の操作を行うことができます。これにより、NHは更新前にクエリを実行し、変更された場合は更新のみ、変更された列のみが実行されます。私はそれがすべての更新のために選択するかどうか、またはそれがセッションにない場合にのみ、わからない。

  • 更新の代わりにMergeを使用してください。これは実際には同じです。セッションにまだ存在していない場合にのみ、データベースからエンティティを選択します。 dynamic-update="true"も使用してください。トレードオフもあります。Mergeは、すでにセッションに1つが​​ある場合に、接続されたインスタンスを返します。したがって、渡されたインスタンスを常に破棄し、Mergeにあるインスタンスで作業する必要があります。

実際には更新された列は気にしません。前のクエリを実行する代わりに、盲目的に更新するほうがおそらく早いでしょう。

+0

データベースにトリガーがありません。まあ、私はプロパティを更新するために使用されたためにこれをやりたいのですが、変更されました。更新オブジェクトが盲目的に速くなり、Mergeに追加のリソースが必要になることを意味しますか? –

+0

ところで、なぜ私はselect-before-update = "true"を使わなければならないのですか? –

+0

Mergeに追加のクエリが必要です。これは追加のdb往復であり、オーバーヘッドがあります。私はselect-before-updateがMergeを避けることだと思います。 Mergeはビジネスロジックに影響を与えます。 –

6

使用mappingの動的更新= "true" を。
はさらに分離オブジェクトの使用、これを更新するには:

Session.SaveOrUpdateCopy(myObject) 
+0

私は答えとしてこれを受け入れたいと思います。もう1つ質問したいだけです:SaveOrUpdateCopyとMergeの違いは何ですか?分離されたオブジェクトに対してMergeを使用できますか、SaveOrUpdateCopyはより良いアプローチですか? –

+0

dynamic-updateは、添付エンティティでのみ機能します。 NHがセッション中に古い状態を持たない場合、どのプロパティが変更されたかはNHがどのように判断するのですか? –

+0

私はなぜそうではありませんが、私は動的更新属性を設定し、SaveOrUpdateCopyまたはマージと言うと、オブジェクトの変更された列のみを保存します。私は動的更新属性を削除すると、NHibernateは1つだけ変更しても、すべてのプロパティを再度保存します!しかし、それがどのように動作するのかは疑問です... –

関連する問題