2009-04-23 12 views
20

私はNHibernateでどのようにFlush(とNHibernate.ISession)が動作するのか混乱しています。NHibernateフラッシュ - どのように動作するのですか?

私のコードでは、ISession.Save(entity)を使ってオブジェクトを保存したときに、そのオブジェクトをデータベースに直接保存することができたようです。

しかし、私は更新しISession.SaveOrUpdate(entity)またはISession.Update(entity)を使用してオブジェクト際に、データベース内のオブジェクトが更新されない---私はそれを更新するためにISession.Flushを呼び出す必要があります。次のように

私はオブジェクトを更新する方法についての手順は次のとおりです。

  1. ISession.Get(typeof(T), id)
  2. 変更にオブジェクトのプロパティを使用して、データベースからオブジェクトを取得し、例えば、myCar.Color="Green"
  3. は戻って、それをコミットデータベースを使用してISession.Update(myCar)

myCarはデータベースに更新されていません。しかし、後でISession.Flushと呼ぶと、更新されます。

Flushを使用する場合、使用しない場合は?

+0

[NHibernate ISession Flushの可能な場所:いつ、いつ、いつ、そしていつ?](http://stackoverflow.com/questions/43320/nhibernate-isession-flush-where-and-when-to -use-it-and-why) – sleske

答えて

28

あなたはNHibernateのがフラッシュしたときに気にする必要はありません。

あなた自身の接続を作成した場合は、を作成する必要があります。NHibernateはコミットするタイミングを知らないためです。

あなたにとって本当に重要なことは、トランザクションです。トランザクション中は、他のトランザクションから隔離されています。つまり、データベースを読み込んだときに変更が常に表示され、コミットされていない限り、他のトランザクションの変更は表示されません。ですから、NHibernateがコミットされていない限り、データベース内のデータをいつ更新するか気にする必要はありません。とにかく誰にも見えません。あなたは、クエリの前

  • をコミット呼び出し
    • 場合

      NHibernateのは、あなたがメモリ内の実際の状態によってフィルタリングすることを確実にするためにフラッシュ

    • あなたはフラッシュ

    例を呼び出すとき:

    using (session = factory.CreateSession()) 
    using (session.BeginTransaction()) 
    { 
        var entity = session.Get<Entity>(2); 
        entity.Name = "new name"; 
    
        // there is no update. NHibernate flushes the changes. 
    
        session.Transaction.Commit(); 
        session.Close(); 
    } 
    

    エンティティはコミット時に更新されます。 NHibernateはあなたのセッションが汚いと判断し、データベースへの変更をフラッシュします。セッションの外で変更を加えた場合にのみ、更新と保存が必要です。 (これは、分離されたエンティティ、すなわちセッションによって知られていないエンティティを意味します)。


    注意パフォーマンス上:フラッシュは、データベースを更新するために必要なSQL文を実行していないだけ。また、メモリ内の変更を検索します。 POCOにはダーティー・フラグがないので、セッション内のすべてのオブジェクトのすべてのプロパティーを第1レベルのキャッシュと比較する必要があります。これはあまりにも頻繁に行われるとパフォーマンス上の問題になる可能性があります。

  • (シリアライズが変更を確認するために必要とされる)
  • 使用read-only entitiesときに適切な
  • シリアライズされたオブジェクトを避け

    • でフラッシュしないでくださいループ:あなたは、パフォーマンスの問題を回避するためにできることがいくつかあります適切な場合はmutable = falseを設定してください
    • プロパティでカスタムタイプを使用する場合、効率的なEqualsメソッドを実装してください。
    • yあなたがしていることを知っている。
  • +0

    ありがとうございます。しかし、データベース内のオブジェクトを更新すると、自分のトランザクションを作成することになりますか?それとも、なぜデータベースを更新するためにflushを呼び出す必要があるのですか? – Graviton

    +1

    それを修正しなければならなかった:独自の接続を作成したときにフラッシュする必要があります。 CreateSessionを呼び出すと、NHibernateから接続が作成されますが、独自のADO.NET接続を提供できます。通常これは必要ありません。これをしないと、flushを呼び出す必要はありません。 –

    6

    NHibernateは、必要なときにのみSQL文を実行します。 SQLステートメントの実行を可能な限り延期します。

    たとえば、IDが割り当てられたエンティティを保存すると、INSERT文の実行を延期する可能性があります。 しかし、例えば、自動インクリメントIDを持つエンティティを挿入すると、NHibernateはこのエンティティに割り当てられるIDを知る必要があるため、エンティティを直接INSERTする必要があります。

    明示的にflushを呼び出すと、NHibernateはそのセッションで変更/作成/削除されたオブジェクトに必要なSQL文を実行します。多くの場合

    Flush

    +0

    リンクが動作しません。 「このコンテンツはKnolでは使用できなくなりました」と表示されます。 – N30

    +0

    @ N30:リンクを修正しました。 –

    関連する問題