none
DBの更新とメモリー上にキャッシュされたデータの関係について RRS feed

  • 質問

  • いつも質問の投稿ばかりで恐縮ですが、どうぞよろしくお願いします。

    毎度の事ですが、詳細に入る前にそもそもやっている事が間違っている
    と言う事でしたら、その辺りのご指摘からお願いします。


    LINQ to SQL を使って、DBの読み書きをしています。
    私の理解の及ぶ範囲では非接続型で動作しており、DBの実態と同期を
    取るには dataContext.SubmitChanges(); が必要と認識しています。

    しかし、メモリー上のデータと読み書きしている分には、各処理の中で
    自由にデータの加工を行い、区切りの付いた所でDBをアップデートすれば
    良いのでは・・と認識しています。
    (ここでは、別の端末からのアクセスは無く、排他制御は考慮する必要
      が無い事を前提に考えています)

    他にも考慮しなければいけない事柄があるからだと思いますが、次のような
    問題が生じ、その原因を探るきっかけが掴めず困っています。
    何か、ヒントでも教えて頂けたらと思い投稿した次第です。


    大雑把な話で申し訳ありませんが、以下のような再現性のある流れまで
    掌握できています。

    アプリの起動で、Form1.csが開きます。 その後・・・

    ① Form1の中からForm2 を開き、DBのデータに処理を加えてその結果をDBに
       返した後、Form1 に戻ります。
      (戻る前に、Form2の中でdataContext.SubmitChanges();を実行)

    ② Form1の中で、①により処理された結果のデータを参照して、別の処理を
       行います。

    この流れでは、意図した通りに動作します。
    (更に他の動作を繰り返すと問題が生じる可能性を否定できませんが・・)


    次に、問題(疑問)が生じるケースです。
    (起動後、このステップで完全に再現します)

    先のケースに準じて ①に於いて Form2を開く前に printDocument1.Print();
    の実行を行うと様子が変わります。
    ②の処理に於いて①による結果のデータを参照すると更新されていません。
    デバッガーで確かめると更新したはずの一連のデータが未更新です。

    しかし、この状態でデータベースエクスプローラで該当データを確認すると
    ①での処理は間違いなくDBに反映しています。

    Form2で更新したデータは、勿論キャッシュ上も更新され、Form1からも同じ
    ものを参照していると思っていますが、何か認識が間違っているようです。
    また、間違いがあるとすると printDocument1.Print();を実行しなかった
    場合に問題が生じないのも不可解です。

    どの辺りを勉強すればいいのか、また攻め所はどこか、先輩方のご教授を
    お願いします。


    ソリューション・エクスプローラで以下の構成が確認できます。

     WindowsFormsApplication1
      ・・・
      DataClasses1.dbml
      Form1.cs
      Form2.cs
      ・・・
      ・・・

    DBの読み書きは、すべて

     var query = from ele in dataContext.テスト
                    where ele.カラム1 == xxx
                    select ele;
     
     yyy = query.First().カラム2;
     query.First().カラム3 = yyy;
     
     dataContext.SubmitChanges();
     
     みたいな感じで行っています。


    みなさん、どうぞよろしくお願いいたします。

    2010年5月15日 14:30

回答

  • その後も、あちこちを調べてみました。

    当面、表面化している問題は、更新されたDBのデータが手元のオブジェクトに
    反映していない事であり、これを更新するためのメソッド refresh() が有る事が
    分かりました。

    先の例で、Form1から戻った直後に、

    dataContext.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, dataContext.テーブル名);

    の1行を追加すると、表面的な問題は解消しました。

    多分、フォームを行き来してDBの更新を行う際に必要な大事な事を理解できていない
    と思われます。  理解が不十分な箇所、勉強するポイントなど、ご教授頂ければ
    嬉しいです。

    どうぞ、よろしくお願いいたします。

    • 回答の候補に設定 山本春海 2010年5月24日 6:23
    • 回答としてマーク 山本春海 2010年5月28日 4:23
    2010年5月16日 7:57
  • printDocument1.Print(); が何なのかを書かれていないので、誰も何も書けないと思います。

    なんとなくのイメージでは、DataContext のインスタンスの作成タイミングと SubmitChanges() の呼び出しタイミングの差異じゃないかなぁっとも思えます。他に「DB に値を返す」という表現が何を示しているかも、いまいちはっきりとしません。SubmitChanges() の呼び出しを指しているのかとも思いましたが、SubmitChanges() の呼び出しについては別記されているので、それ以外の何かをされているのではないかとも思えます。

     

    • 回答の候補に設定 山本春海 2010年5月24日 6:23
    • 回答としてマーク 山本春海 2010年5月28日 4:23
    2010年5月17日 3:43

すべての返信

  • その後も、あちこちを調べてみました。

    当面、表面化している問題は、更新されたDBのデータが手元のオブジェクトに
    反映していない事であり、これを更新するためのメソッド refresh() が有る事が
    分かりました。

    先の例で、Form1から戻った直後に、

    dataContext.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, dataContext.テーブル名);

    の1行を追加すると、表面的な問題は解消しました。

    多分、フォームを行き来してDBの更新を行う際に必要な大事な事を理解できていない
    と思われます。  理解が不十分な箇所、勉強するポイントなど、ご教授頂ければ
    嬉しいです。

    どうぞ、よろしくお願いいたします。

    • 回答の候補に設定 山本春海 2010年5月24日 6:23
    • 回答としてマーク 山本春海 2010年5月28日 4:23
    2010年5月16日 7:57
  • printDocument1.Print(); が何なのかを書かれていないので、誰も何も書けないと思います。

    なんとなくのイメージでは、DataContext のインスタンスの作成タイミングと SubmitChanges() の呼び出しタイミングの差異じゃないかなぁっとも思えます。他に「DB に値を返す」という表現が何を示しているかも、いまいちはっきりとしません。SubmitChanges() の呼び出しを指しているのかとも思いましたが、SubmitChanges() の呼び出しについては別記されているので、それ以外の何かをされているのではないかとも思えます。

     

    • 回答の候補に設定 山本春海 2010年5月24日 6:23
    • 回答としてマーク 山本春海 2010年5月28日 4:23
    2010年5月17日 3:43