Help us understand the problem. What is going on with this article?

EntityFrameworkについて

More than 1 year has passed since last update.

仕事でEntityFrameworkを使うかもしれないので、今のところの知識をまとめてみました。

EntityFrameworkとは?

Ruby on RailsにおけるActiveRecord の .NETバージョン。O/Rマッパー。

ActiveRecordに相当するのは、POCOエンティティ(Plain Old CLR Object)という、プロパティだけを持つクラスです。ただ、これはRailsのActiveRecordのように自動生成されずユーザーが自作します。

student.cs
public class Student
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
}

こんな感じのエンティティをModelフォルダ内に作ります。

そしてこのデータをDBから読み込むためにSystem.Data.Entity.DbContextを継承したコンテキストクラスを作ります。

MyContext.cs
// DbContext を継承する必要がある
public class MyContext : DbContext
{
    public DbSet<Student> Students { get; set; }
    public DbSet<Teacher> Teachers { get; set; }
}

プロジェクトをビルドしたタイミングで、コンテキストクラスと同名のデータベースが、そのDB内にPOCOエンティティと同名のテーブルが、自動生成されます。

DBのテーブルにアクセスする際は、このコンテキストクラスのプロパティを使います。

DBからデータを読み込むには↓のようにします。

example_read.cs
using (var context = new MyDbContext())
{
   var student = context.Students.Find(x => x.Name == "Yuichi"); //Find()のタイミングでクエリ発行
   var students = context.Students.Where(x => x.Age <= 20).ToArray(); //ToArray()のタイミグでクエリ発行

    //...
}

usingを使っているのは、コンテキストクラスを確実にDisposeするためです。
また、上記2クエリはFindメソッドが実行されるタイミング、ToArrayメソッドが実行されるタイミングでそれぞれ、DBに対してクエリが発行されています。
ですので、クエリが発行されるタイミングを意識して、使用時には不要なDBアクセスを極力抑えるように注意する必要があります。

データの追加、更新、削除は↓のようにやります。

example_update.cs
using (var context = new MyDbContext())
{
    // 追加
    // Addした段階ではSql文はDBに発行されない
    context.Students.Add(new Student
    {
        Name = "Daisuke",
        Age = 18
    });
    //更新
  var student = context.Students.Find(x => x.Name == "Yuichi"); //Find()のタイミングでクエリ発行
    student.Age = 26;
    //削除
    var deleteTarget = context.Students.Find(x => x.Name == "Takashi");
    context.Students.Remove(deleteTarget);
    // SaveChangesが呼び出された段階で初めてInsert,Update,Delete文が発行されます
    context.SaveChanges();
}

通常は、更新、削除処理はDBContext経由で読みだした(Find、Whereで読み込んだ)データに対してのみ行なえます。
しかし、例えば削除対象のデータの主キーが予めわかっている場合は、そのデータを事前に読み込むのは冗長な気がします。
そんなときは、Attachメソッドを使います。

example_attach.cs
    using (var context = new MyDbContext())
    {
   //削除(削除対象のIDが予めわかっている時)
        var deleteTarget = new Student { Id = 1 };
        context.Students.Attach(deleteTarget);
        context.Students.Remove(deleteTarget);

        context.SaveChanges();
    }

データベースファーストについて

この記事で紹介したのは、まずPOCOエンティティを作って、それに合わせて自動的にDBが作成される、いわゆるコードファーストという手法です。
(EntityFramework自体はこのコードファーストという手法をAsp.NET MVCで実現する為に考案されたものです)
しかし、既にデータベースが存在している場合は、既存のテーブルからPOCOエンティティを作成する必要があります。
これをデータベースファースといいます。
これについては、また記事を分けてまとめていきたいと思います。

jmty
日本最大のクラシファイドサイト「ジモティー」を開発・運営するスタートアップ
http://jmty.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away