Edited at

EntityFrameworkについて

仕事で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エンティティを作成する必要があります。

これをデータベースファースといいます。

これについては、また記事を分けてまとめていきたいと思います。