Blog ブログ
へっぽこプログラマの奮闘記 ~第1回:データベースが更新されません~
やりたかった事は「データベースに指定したIDのデータが存在した場合は上書き。無ければ新たにレコードを新規作成する」という事です。その時のコードを再現したものをどうぞご覧ください。
ところが、いざ動かすと「値が更新されない!!!」という事態に陥ってしまいました。。。(ちなみにDBへのレコード追加は普通にできていました)
さて、なぜ今回こんな事が起きてしまったかというと、実はこのコードは「更新の処理でDBのデータへの参照を思いっきり上書きしている」コードなので更新できなかったのです。
どういう事かを図と合わせてもう少し詳しく説明しましょう。
そもそも Entity Framework の DbSet<TEntity> は「データベースに対してクエリを発行し、その結果をメモリに保持する」動きをします。今回のコードでは26,27行目でその処理を行っています。
実はこのメモリに保持されたデータはAdded(追加)、Unchanged(変更なし)、Modified(変更あり)の3種類の状態を持っています。
データベースからデータを取得する際、Unchangedの状態で結果をメモリに保持します。
データに変更を加えると状態はModifiedに変わり、Addメソッドを使ってレコードを追加するとAddedの状態に変わります。
SaveChanges()が呼ばれた時に初めてModifiedの状態のものは変更され、Addedのものはレコードが追加されるようになるのです。
そして今回の失敗はメモリにせっかく確保したデータベースのデータの参照をnewしたデータの参照で上書きをしてしまったため、データベースのデータはUnchangedの状態のまま変わる事がなく、結果データベースの値がSaveChanges()を呼び出しても更新されないという事態が発生してしまったものです。
サーバーのプログラムはこんな感じの動きをしています↓
じゃあ、このコードはどうやったら値を更新してくれるのかといいますと、
こうすることでメモリに保持されているデータに変更が加わり、Modifiedの状態になるので、SaveChanges()を呼び出すと値が正常に更新されるようになります。
まとめ
Entity Framework がどうやって動いているかを知らないと、こんなミスを起こしてしまうんですね。。。
まだまだわからない事がたくさんあり、今後多くの壁にぶち当たっていくことにはなると思いますが、たくさん勉強して少しでも早く先輩社員に追いついて、一人前のプログラマになるべく、これからも奮闘して参ります。
長くなりましたが、これからもどうぞよろしくお願いします。