2016年10月8日土曜日

VB EF6 PrimaryKey について

Entity Framework を触り出しています。
データベースを扱えれば、 色々と便利な機能が使えますし、
独自の定義ではない 規格下のデータを蓄積出来ますから。  後々、潰しの利くデータが残る、と。
でも、やはり、新しい技術は大変です。  覚えるのが。


特に、注意したいのが、 Primary Key (PK プライマリーキー) の扱いです。

データベース上で、その Record (レコード)が一意に識別出来る様に付けるのが Primary Key ですね。
他のものと重複していない、 Unique (ユニーク) なもので、必ず値を付けなければいけません。
でも、データベース上で、その値の書き換えは禁止されてはいません。
未だ使われていない 新しい 値 に変更する事は、 制約違反には該当しません。  当然ですが。.
一般的ではありませんが、別に無くても良い訳です、 Primary Key 。.

ところが、ところが、 です。

Entity Framework は、
フロントエンド(プログラム)のレコードとデータベースとの関連を この Primary Key で管理しています。
ですから、この値を書き直そうとすれば、 駄目!~ と お叱り を受けます。
Entity Framework 曰く、
Additional information: The property 'ID' is part of the object's key information and cannot be modified.
折角、複雑な関係を結び付けて問題が生じない様に調整してるのだから、
その値を弄るのは止めて下さい!。
おかしくなっちゃうでしょう!。
そんな処でしょうか。

確かに、Relation を張り巡らした Database の PK や FK を、
無闇に、後から弄り廻すものではありません。
内容に依っては、相当な数のデータ修正に結び付く場合もありますし、
作業手順を間違えば、 Database そのものを破壊してしまう(整合しなくなる) ケースも考えられるからですね。

しかし、 人のやる事。
ケアレスミスはつきものですし、 参照系の主キーを振り直して新たなグループ(データ)を加える場合だってあります。

単純に、 Entity Framework を使って、表形式( WPF なら DataGrid、 Form なら DataGridView ) に、
Table を引っ張ったとしましょうか。
標準で、これらには編集機能があります。
Primary Key にしてある Column も お構い無し に 編集を し掛けます。
そして、保存機能が実装してあれば ... 。
先程の Error Message とご対面と相成ります。

さて、困った!。


Entity Framework も、そこ迄、自動で面倒を見てくれる訳ではありません。


基本は、 Primary Key  の箇所は ReadOnly に!。  でしょうね。


そして、どうしても変えたい! となれば、
  内容をコピーした新規行を追加して 該当箇所を訂正の上 既存行を削除するか、
  Database を直接書き換える Update Query を発行するか、
です。
Update Query は Visual Basic なら、

        Dim updateQuery As String = "UPDATE TableA SET ID = @newID WHERE ID = @oldID"
        myEntities.Database.ExecuteSqlCommand(updateQuery, _
                                              New System.Data.SqlClient.SqlParameter("@oldID", Me.TextBoxA_from.Text), _
                                              New System.Data.SqlClient.SqlParameter("@newID", Me.TextBoxB_to.Text) _
                                                                    )

こんな感じのコードでしょうか。

勿論、直接 DataBase を書き換えていますので、 ..SaveChanges() は不要です。


但し、そう、但し、 です。
この書き換え手段は、 使い易くしては いけません。
識別用途の値を書き換える訳ですから、 普段とは違う事をしている と思わせるべきです。
思うに、 この様な訂正が必要になるのは、 ケアレスミスによる 登録間違い でしょうか。
ケアレスミスの訂正時って、 大体、慌てふためいている場合が多く、 ミスの重ね塗り が多いからです。
Primary Key 書き換えは、 常套手段ではない、非常時対応、 と 心するべき です。
操作が面倒な位の ユーザーインターフェスにして置かれるのをお勧めします。
     つまり、 通常の 追加や削除や一般項目編集 と異なり、煩雑な手順を経て やっと 実行出来る様に です。.

因みに、 データベース上での、この様な書き換えは、必ずしも、値の変更を直接その場所で行うとは限りません。
ファイルシステムも似ています。
既存コピー > コピーの値変更 > 変更後保存> 既存削除 と作業して置けば、
場合によっては、 作業をやり直せる可能性も出て来ます。
  (直接操作してしまえば、その可能性は、極めて低くなります。)
それ故、 ブロックの断片化が問題になるケースが出て来る訳ですが ... 。
 そして、朧げな記憶ですが、
 SQL Server をはじめとする RDMS では、 PK の変更で順番が変わると、実データの並び替えが起こる筈です。
 パフォーマンスへの影響が考えられるので、 Database 設計も含めた 対策 をする必要があった記憶があります。
更に、一歩進んで、一切削除せず、有効無効の列を設ける方法だってありますし ... 。
そう、登録データの削除を許さない Database だってある訳です。  あっ、 また、脱線。.


尚、これらは、参照系のマスタを操作する前提で書いています。



[2016/10/09] code 改行編集

0 件のコメント:

コメントを投稿