エンティティフレームワーク-データベース操作

前の章では、エンティティデータモデルを定義する3つの異なる方法を学びました。

  • それらのうちの2つ、データベースファーストとモデルファーストは、コード生成と組み合わせたEntityFrameworkデザイナーに依存していました。

  • 3番目のCodeFirstでは、ビジュアルデザイナーをスキップして、独自のコードを作成できます。

  • 選択したパスに関係なく、最終的にはドメインクラスになり、1つ以上のEntity Framework DbContextクラスを使用すると、それらのクラスに関連するデータを取得して永続化できます。

アプリケーションのDbContextAPIは、クラスとデータベースの間のブリッジとして使用されます。DbContextは、EntityFrameworkで最も重要なクラスの1つです。

  • クエリの表現と実行が可能になります。

  • データベースからクエリ結果を取得し、それらをモデルクラスのインスタンスに変換します。

  • 追加や削除など、エンティティへの変更を追跡し、オンデマンドでデータベースに送信される挿入、更新、削除ステートメントの作成をトリガーできます。

以下は、この章でさまざまな操作を実行するドメイン広告コンテキストクラスです。これは、「データベースファーストアプローチ」という章で作成したものと同じ例です。

コンテキストクラスの実装

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;

namespace DatabaseFirstDemo {

   public partial class UniContextEntities : DbContext {

      public UniContextEntities(): base("name = UniContextEntities") {}

      protected override void OnModelCreating(DbModelBuilder modelBuilder) {
         throw new UnintentionalCodeFirstException();
      }

      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }
}

ドメインクラスの実装

コースクラス

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic;
	
   public partial class Course {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Course() {
         this.Enrollments = new HashSet<Enrollment>();
      }
	
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
	
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]
			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

学生クラス

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic; 

   public partial class Student {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Student() {
         this.Enrollments = new HashSet<Enrollment>();
      }

      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public System.DateTime EnrollmentDate { get; set; }

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]
			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

登録クラス

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic; 

   public partial class Enrollment {

      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Nullable<int> Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }
}

操作の作成

Entity Frameworkを使用した新しいオブジェクトの追加は、オブジェクトの新しいインスタンスを作成し、DbSetのAddメソッドを使用して登録するのと同じくらい簡単です。次のコードを使用すると、データベースに新しい学生を追加できます。

class Program {

   static void Main(string[] args) {

      var newStudent = new Student();

      //set student name

      newStudent.FirstMidName = "Bill";
      newStudent.LastName = "Gates";
      newStudent.EnrollmentDate = DateTime.Parse("2015-10-21");
      newStudent.ID = 100;

      //create DBContext object

      using (var dbCtx = new UniContextEntities()) {

         //Add Student object into Students DBset
         dbCtx.Students.Add(newStudent);

         // call SaveChanges method to save student into database
         dbCtx.SaveChanges();
      }
   }
}

更新操作

既存のオブジェクトの変更は、変更するプロパティに割り当てられた値を更新し、SaveChangesを呼び出すだけです。たとえば、次のコードを使用して、Aliの姓をKhanからAslamに変更します。

using (var context = new UniContextEntities()) {

   var student = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
   student.LastName = "Aslam";
   context.SaveChanges();
}

削除操作

Entity Frameworkを使用してエンティティを削除するには、DbSetのRemoveメソッドを使用します。既存のエンティティと新しく追加されたエンティティの両方の作品を削除します。追加されたがまだデータベースに保存されていないエンティティに対してRemoveを呼び出すと、エンティティの追加がキャンセルされます。エンティティは変更トラッカーから削除され、DbContextによって追跡されなくなります。変更が追跡されている既存のエンティティでRemoveを呼び出すと、次にSaveChangesが呼び出されたときに削除するエンティティが登録されます。次の例は、名がAliであるデータベースから学生が削除されるコードの例です。

using (var context = new UniContextEntities()) {
   var bay = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
   context.Students.Remove(bay);
   context.SaveChanges();
}

読み取り操作

データベースから既存のデータを読み取るのは非常に簡単です。以下は、Studentテーブルからすべてのデータを取得し、プログラムが学生の姓名とともにアルファベット順に表示されるコードです。

using (var db = new UniContextEntities()) {

   var query = from b in db.Students orderby b.FirstMidName select b;
   Console.WriteLine("All All student in the database:");

   foreach (var item in query) {
      Console.WriteLine(item.FirstMidName +" "+ item.LastName);
   }

   Console.WriteLine("Press any key to exit...");
   Console.ReadKey();
}