データ取得・変更のためのその他の機能

データ取得・変更のためのその他の機能


【関連を持ったエンティティの操作】

データの挿入

新規にオブジェクトを挿入する場合、Addメソッドで追加する。
以下はCommentオブジェクトを新規追加すると同時に、ナビゲーションプロパティであるArticle
に対してArticleオブジェクトを新規追加し設定している。

コントローラー[OtherController.vb]

ビュー[なし]
URLに「http://~コントローラー/アクション」と指定してInsertアクションを実行
arrow_down
[出力結果(画面)]
71
[DB(Comments)]
72
[DB(Articles)]
73
※両テーブルともIdはInsertアクションを実行するたびに毎回自動でインクリメントされる。
 (そういう設定をしたつもりはなかったが・・・)


また、既存のArticleに対して、新規のCommentオブジェクトを関連付ける場合、
ナビゲーションプロパティArticleに対して参照先のArticleオブジェクトを設定する。
以下はId=2のArticleに対してCommentを追加した例
コントローラー[OtherController.vb]

arrow_down
[DB(Comments)]
74
※外部キープロパティを定義しており、Articleオブジェクトのid値が分かっている場合、
 「.Article = article」の代わりに「.ArticleId = 2」としてもいい。

データの更新

既存の関連付けを変更する場合も、ナビゲーションプロパティか外部キープロパティに対して、
関連先のオブジェクト or Id値を設定するだけ。

コントローラー[OtherController.vb]

[DB(Comments)]
75_b
arrow_down
[DB(Comments)]
75_a

データの削除

以下は、Id=9のArticleオブジェクトを削除する例だが、外部キーでArticleを参照しているCommentオブジェクト
も同時に削除される例(C#では、外部キー参照している場合、エラーとなるみたいだが・・・)

コントローラー[OtherController.vb]

【SQLを直接指定する(SqlQuery/ExecuteSqlCommandメソッド)】

Entity FrameworkではLINQ to Entitiesを利用すべきだが、複雑な問い合わせについては、LINQ to Entities
で表現するのが困難な状況もある。
その場合、DatabaseクラスのSqlQueryメソッドとExecuteSqlCommandメソッドを利用する。
※ただ、多用するとEntity Frameworkを利用する意味が損なわれるので注意
・SqlQueryメソッド:SELECT文実行
・ExecuteSqlCommandメソッド:INSERT/UPDATE/DELETE文実行

SqlQueryメソッドでは、型(以下の例ではComment)を指定することで、SELECT結果をオブジェクトとして
取得できる。

コントローラー[CommentsController.vb]

【トランザクション処理を実装】

Entity Frameworkでは、SaveChangesやExecuteSqlCommandメソッドによるDBへの反映を一つのトランザクション
として実行するため、あまりトランザクションを意識する必要はない。
以下の例では、1件でもINSERTに失敗すれば2件ともロールバックされDBには反映されない。

コントローラー[OtherController.vb]

明示的なトランザクションの開始

SaveChangesやExecuteSqlCommandメソッドによる処理を一つのトランザクションとしてまとめたい場合、
明示的にトランザクションを宣言する必要がある。
Database.BeginTransactionメソッドでトランザクションを開始し、その結果をDbContextTransactionオブジェクト
として返す。そのDbContextTransactionオブジェクトを介してコミット・ロールバックを行う。

コントローラー[OtherController.vb]

【同時実行制御を実装する/Timestamp属性】

通常同一のレコードに対して複数のユーザーが同時に更新しようとすると競合が発生する。
Entity Frameworkでは、このような問題を防ぐためにオプティミスティック同時実行制御(楽観的同時実行制御)
の仕組みを提供している。
具体的な方法は以下のとおり。

①エンティティにTimestamp列を準備する

Entity Frameworkでは、エンティティ(レコード)の単位にバージョン番号を管理することで競合の有無を
検出する。バージョン管理列を作成するには、プロパティにTimestamp属性を付与する。
プロパティの型はByte()型とする。
※DBにも(自動)マイグレーション等の方法で列を追加する必要がある。
 Timestamp属性を付与したプロパティは、DBではtimestamp型のフィールドとして定義される。
timestamp列には、データを更新するタイミングで自動的にバージョンを表す数値が設定されるので、
Entity Frameworkではこれを利用して競合を検出する。

モデル[Article.vb]

②ビュースクリプトを修正する