ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

ADO.NETでCRUDしようと思ってるけどなかなかうまくいかなくてつらい

DbContextとDbSetを使ってCRUDやろうと思ってるのですが、なかなかうまくいかなくて積んでました。ひとまずCreateとReadはできるようになったので忘れないうちに。

DbContextはIDisposableインターフェースを実装している

見出しの通りです。必要なところでusing使いましょう。なんかちゃんとDisposeしないとトランザクションがコミットされていない感じがします。なぜか保存されてなくてはまったのですがこれが原因っぽいです。usingを使えばよきに計らって何が起きてもDisposeしてくれるので積極的に使いましょう。

Readのしかた

DbContextを継承したクラスのインスタンスに、対応するモデルのコレクションクラスを作り、そこに対してLINQでアクセスすれば内部的にSQLを発行する仕組みらしいです。

Createのしかた

DbContextを継承したクラスのインスタンスに、対応するモデルのコレクションを入れるプロパティを作って、そこにモデルのインスタンスをAdd()で投げこんでいけばOKです。デザインツールがあるのでありがたく使いましょう。もろもろ済んだらSaveChanges()を呼び出して保存します。

using (var context = new MyDbContext())
{
    var entity = MyDbContext.Entity.Add(new Entity());
    entity.hoge = "hoge";
    entity.fuga = "fuga";
    context.SaveChanges();
}

デザインツールの使い方

ソリューションエクスプローラーの適当なところで右クリック→追加→新しい項目(Ctrl+Shift+A)でダイアログが出るので、「ADO.NET Entity Data Model」を選択、適当に名前を付けて「追加(A)」ボタンを押します。
すると間髪入れずにウィザードが起動するので、データベースが既にあるのであれば「データベースから生成」、ない場合は「空のモデル」を選びます。以降は「データベースから生成」の場合について説明します。
サーバーエクスプローラーですでにどこかのデータベースに接続していると、それがプルダウンメニューに出てきます。超親切設計ですね。ない場合も、「新しい接続」ボタンを押すとデータベースを選択できます。もちろん選択したデータベースは自動的にサーバーエクスプローラーにも追加されます。
次で終わりです。ここで「次へ」を押すと、データベースからスキーマ情報を取得して、マッピングしたいテーブルとビューを選択できます。適当に取捨選択したら「完了」を押します。これでDbContextクラスを継承したデータベースを抽象化したクラスと、カラムに対応するプロパティのみを持ったモデルクラスができあがります。

同期のとり方

データベースとモデルの同期をとるには、モデルのデザインツールの余白を右クリックして、「データベースからモデルを更新」を選ぶとできます。逆っぽい「モデルからデータベースを生成」は私の手元ではなぜかうまくいきませんでした。

はまりどころ

主キーの設定をお忘れなく

主キーは自動生成されるので、StorageGeneratedPatternプロパティをIdentifyに設定しておかないとバリデーションに引っかかります。外部キーは対応するモデルを渡しておくとCreate時に自動で追加してくれるようなので、こちらはNoneで大丈夫です。