エンティティフレームワーク-リレーションシップ
リレーショナルデータベースでは、リレーションシップは、外部キーを介してリレーショナルデータベーステーブル間に存在する状況です。外部キー(FK)は、2つのテーブルのデータ間のリンクを確立および適用するために使用される列または列の組み合わせです。次の図には、3つのテーブルが含まれています。
- Student
- Course
- Enrollment
上の図では、テーブル間のある種の関連付け/関係を確認できます。テーブル間の関係には3つのタイプがあり、異なるテーブル間の関係は、関連する列がどのように定義されているかによって異なります。
- 1対多の関係
- 多対多の関係
- 1対1の関係
1対多の関係
1対多の関係は、最も一般的なタイプの関係です。
このタイプの関係では、テーブルAの行はテーブルBの多くの一致する行を持つことができますが、テーブルBの行はテーブルAの1つの一致する行のみを持つことができます。
外部キーは、関係の多端を表すテーブルで定義されています。
たとえば、上の図では、StudentテーブルとEnrollmentテーブルには1つの関係があり、各学生には多くの登録がありますが、各登録は1人の学生にのみ属します。
エンティティフレームワークでは、これらの関係はコードを使用して作成することもできます。以下は、1対多の関係に関連付けられている学生クラスと登録クラスの例です。
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Enrollment {
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
上記のコードでは、StudentクラスにEnrollmentのコレクションが含まれていますが、Enrollmentクラスには単一のStudentオブジェクトが含まれていることがわかります。
多対多の関係
多対多の関係では、テーブルAの行はテーブルBの多くの一致する行を持つことができ、その逆も可能です。
このような関係を作成するには、ジャンクションテーブルと呼ばれる3番目のテーブルを定義します。このテーブルの主キーは、テーブルAとテーブルBの両方の外部キーで構成されます。
たとえば、StudentテーブルとCourseテーブルには、これらの各テーブルからEnrollmentテーブルへの1対多の関係によって定義される多対多の関係があります。
次のコードには、Courseクラスと上記の2つのクラスが含まれています。 Student そして Enrollment。
public class Course {
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
CourseクラスとStudentクラスの両方に、ジャンクションクラスEnrollmentを介して多対多の関係を作成するEnrollmentオブジェクトのコレクションがあることがわかります。
1対1の関係
1対1の関係では、テーブルAの行にテーブルBの一致する行を1つだけ含めることができ、その逆も同様です。
関連する両方の列が主キーであるか、一意の制約がある場合、1対1の関係が作成されます。
1対1の関係では、主キーは追加で外部キーとして機能し、どちらのテーブルにも個別の外部キー列はありません。
このタイプの関係は一般的ではありません。この方法で関連するほとんどの情報がすべて1つのテーブルにあるためです。あなたは1対1の関係を使用するかもしれません-
- 多くの列を持つテーブルを分割します。
- セキュリティ上の理由から、テーブルの一部を分離します。
- 有効期間が短く、テーブルを削除するだけで簡単に削除できるデータを保存します。
- メインテーブルのサブセットにのみ適用される情報を格納します。
次のコードは、学生の電子メールIDとパスワードを含む別のクラス名StudentProfileを追加するためのものです。
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual StudentProfile StudentProfile { get; set; }
}
public class StudentProfile {
public StudentProfile() {}
public int ID { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public virtual Student Student { get; set; }
}
StudentエンティティクラスにはStudentProfileナビゲーションプロパティが含まれ、StudentProfileにはStudentナビゲーションプロパティが含まれていることがわかります。
各学生は、大学のドメインにログインするための電子メールとパスワードを1つだけ持っています。これらの情報はStudentテーブルに追加できますが、セキュリティ上の理由から、別のテーブルに分けられています。