血糖値管理をWebアプリにする③ 理解のまとめ1

プログラミング

Entity Framework Core には、データモデルクラスに ナビゲーションプロパティ を設定することで、複数のエンティティ(テーブル)を結合して扱うことができます。

ナビゲーションプロパティ について、チュートリアルで学んで理解したことをまとめておきたいと思います。

チュートリアルに掲載されているデータモデルクラスを、以下に示します。

データモデルクラスは、Student.cs、Enrollment.cs、Course.cs の3つです。

それぞれの赤字の部分が、ナビゲーションプロパティ です。

Student.cs
namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }
 
        public ICollection<Enrollment> Enrollments { get; set; }
    }
}
Enrollment.cs
using System.ComponentModel.DataAnnotations;
 
namespace ContosoUniversity.Models
{
    public enum Grade
    {
        A, B, C, D, F
    }
 
    public class Enrollment
    {
        public int EnrollmentID { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
        [DisplayFormat(NullDisplayText = “No grade”)]
        public Grade? Grade { get; set; }
 
        public Course Course { get; set; }
        public Student Student { get; set; }
    }
}
Course.cs
using System.ComponentModel.DataAnnotations.Schema;
 
namespace ContosoUniversity.Models
{
    public class Course
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }
 
        public ICollection<Enrollment> Enrollments { get; set; }
    }
}

次に、データモデルのテーブルに実際にデータを入れたらどうなるかを見てみましょう。

下記は、Studentテーブル、Courseテーブル、Enrollmentテーブルにチュートリアルで使っているデータの一部を入れたものです。

Student
IDFirstMidNameLastNameEnrollmentDate
1CarsonAlexander2019/9/1
2MeredithAlonso2017/9/1
3ArturoAnand2018/9/1
4GytisBarzdukas2017/9/1
Course
CourseIDTitleCredits
1050Chemistry3
4022Microeconomics3
4041Macroeconomics3
1045Calculus4
3141Trigonometry4
2021Composition3
2042Literature4
Enrollment
StudentIDCourseIDGrade
11050A
14022C
14041B
21045B
23141F
22021F
31050 
41050 

Student テーブル の主キー(ID列)と Enrollment テーブル の対応する外部キー(StudentID列)が関連しています。
Course テーブル の主キー(CouseID列)と Enrollment テーブル の対応する外部キー(CouseID列)が関連しています。

Student テーブル と Enrollment テーブル 間は 1対多 の関係です。
Course テーブル と Enrollment テーブル 間も 1対多 の関係です。

Student テーブル から Enrollment テーブル を見ると、 Enrollment 側 が「多」、
同じように
Course テーブル から Enrollment テーブル を見ると、 Enrollment 側 が「多」
ということになります。

この関係をデータモデルクラスで表現すると、
public ICollection<Enrollment> Enrollments { get; set; }
と表現します。

これを ナビゲーションプロパティ と呼び、相手が「」の関係の ナビゲーションプロパティ を コレクションナビゲーション といいます。

次に、EnrollmentテーブルからStudentテーブルを見ると、相手は「一」の関係です。
また、EnrollmentテーブルからCourse テーブルを見ると、相手は「一」の関係です。

この関係をデータモデルクラスで表現すると
public Course Course { get; set; }
public Student Student { get; set; }
と表現します。

これもナビゲーションプロパティと呼び、相手が「」の関係のナビゲーションプロパティを参照ナビゲーションといいます。

データモデルクラスにナビゲーションプロパティを指定すると、SQL文でテーブル結合をしたときのように、複数のテーブルのデータを関連づけて、一括して処理することができるようになります。

チュートリアルでは、次のコードで関連づけたテーブルを一括処理しています。

    Student = await _context.Students
        .Include(s => s.Enrollments)
        .ThenInclude(e => e.Course)
        .AsNoTracking()
        .FirstOrDefaultAsync(m => m.ID == id);

このコードは、Include()メソッドとThenInclude()メソッドを使用して、関連するデータを一括で読み込んでいます。
Include()メソッドは、Studentsテーブルからデータを取得するときにEnrollmentsテーブルとCourseテーブルのデータも取得します。
Include(s => s.Enrollments)の部分で、StudentレコードのEnrollmentsに対する外部キーで、Enrollmentsから一致するデータすべてを抽出します。
ThenInclude()メソッドは、Enrollmentsテーブルからデータを取得するときにCourseテーブルのデータも取得します

今回は、ナビゲーションプロパティについて、チュートリアルで学習したり、調べたりして理解したことをまとめました。

追記
チュートリアルで理解して、これはまとめておいた方がよさそうだ、と思った事柄について「血糖値管理をWebアプリにする③ 理解のまとめ」シリーズで掲載していきます

タイトルとURLをコピーしました