9.7 翻譯系列:EF數據註解特性之--InverseProperty【EF 6 Code-First系列】

原文連接:https://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspxhtml

EF 6 Code-First系列文章目錄:數據庫

當兩個實體之間不止一種關係的時候,能夠使用InverseProperty特性,爲了理解InverseProperty特性咱們來作一個例子:
1.建立一個控制檯應用程序,安裝好EF:
enter description here
2.建立Course類:app

public class Course
    {
        public int CourseId { get; set; }

        public string CourseName { get; set; }

        public string Description { get; set; }

        public Teacher OnlineTeacher { get; set; }
    }

3.建立Teacher類:ide

public class Teacher
    {
       public int TeacherId { get; set; }

       public string Name { get; set; }

       public ICollection<Course> OnlineCourses { get; set; }
    }

上面的代碼例子中,Course和Teacher實體之間是一對多的關係,一個Teacher能夠教不少的Online Course。
3.建立上下文類:測試

public class EFDbContext:DbContext
    {
        public EFDbContext() : base("name=Constr") { }

        public DbSet<Course> Courses { get; set; }

        public DbSet<Teacher> Teachers { get; set; }
    }

4.SQL連接字符串:ui

<!--SQL連接字符串-->
  <connectionStrings>
    <add name="Constr" connectionString="Server=.;Database=EFAnnotationInversePropertyDB;uid=sa;pwd=Password_1" providerName="System.Data.SqlClient"/>
  </connectionStrings>

5.測試代碼:spa

class Program
    {
        static void Main(string[] args) {
            using (var db = new EFDbContext())
            {
                List<Course> lstModel = db.Courses.ToList();
            }
            Console.WriteLine("success");
            Console.ReadKey();
        }
    }

6.運行程序:
enter description here
能夠看到,根據默認的約定,生成的數據庫以下:
enter description here.net

如今假設Course和Teacher實體之間,還有一個一對多的關係:
Course類:翻譯

public class Course
    {
        public int CourseId { get; set; }

        public string CourseName { get; set; }

        public string Description { get; set; }

        public Teacher OnlineTeacher { get; set; }

        public Teacher ClassRoomTeacher { get; set; }
    }

Teacher類:3d

public class Teacher
    {
       public int TeacherId { get; set; }

       public string Name { get; set; }

       public ICollection<Course> OnlineCourses { get; set; }

       public ICollection<Course> ClassRoomCourses { get; set; }
    }

在上面代碼例子中,Course和Teacher實體有兩個一對多的關係。一門課程能夠被一個Online Teacher教,也能夠被一個class-room Teacher教。一樣一個教師能夠教多個Online Course,也能夠教多個class-room Course.
刪掉以前生成的數據庫後,咱們運行一下程序:
enter description here
看看生成的數據庫:
enter description here
看到,EF爲咱們在Course表中,生成了4個外鍵。爲了解決這個問題,咱們使用InverseProperty特性。修改一下Teacher類的代碼:
Teacher類:

public class Teacher
    {
       public int TeacherId { get; set; }

       public string Name { get; set; }

       [InverseProperty("OnlineTeacher")]
       public ICollection<Course> OnlineCourses { get; set; }

       [InverseProperty("ClassRoomTeacher")]
       public ICollection<Course> ClassRoomCourses { get; set; }
    }

Course類:

public class Course
    {
        public int CourseId { get; set; }

        public string CourseName { get; set; }

        public string Description { get; set; }

        public Teacher OnlineTeacher { get; set; }

        public Teacher ClassRoomTeacher { get; set; }
    }

在上面的例子中,InverseProperty特性應用在兩個集合類型的導航屬性OnlineCourses和ClassRoomCourses上,而後指定它們在Course實體中的相關聯的導航屬性,因此如今EF就能分辨出來相應的外鍵。EF 6將建立兩個外鍵:OnlineTeacher_TeacherIdClassRoomTeacher_TeacherId。對於EF Core將會建立OnlineTeacherTeacherIdClassRoomTeacherTeacherId兩個外鍵。
而後在刪除數據庫,從新運行一下程序:
enter description here

看一下生成的數據庫:
enter description here

能夠看到如今生成的數據庫就是正確的了。
進一步配置,你能夠使用ForeignKey特性來配置外鍵名稱:
Course類:

public class Course
    {
        public int CourseId { get; set; }

        public string CourseName { get; set; }

        public string Description { get; set; }

        [ForeignKey("OnlineTeacher")]
        public int OnlineTeacherId { get; set; }
        public Teacher OnlineTeacher { get; set; }

        [ForeignKey("ClassRoomTeacher")]
        public int ClassRoomTeacherId { get; set; }
        public Teacher ClassRoomTeacher { get; set; }
    }

Teacher類:

public class Teacher
    {
       public int TeacherId { get; set; }

       public string Name { get; set; }

       [InverseProperty("OnlineTeacher")]
       public ICollection<Course> OnlineCourses { get; set; }

       [InverseProperty("ClassRoomTeacher")]
       public ICollection<Course> ClassRoomCourses { get; set; }
    }

上面代碼中,咱們在Corse類中添加兩個屬性列,配置外鍵,如今刪除數據庫,從新運行一下:
enter description here
看到報錯了,咱們修改一下Course類:
Course類最終代碼:

public class Course
    {
        public int CourseId { get; set; }

        public string CourseName { get; set; }

        public string Description { get; set; }

        [ForeignKey("OnlineTeacher")]
        public int? OnlineTeacherId { get; set; }
        public Teacher OnlineTeacher { get; set; }

        [ForeignKey("ClassRoomTeacher")]
        public int? ClassRoomTeacherId { get; set; }
        public Teacher ClassRoomTeacher { get; set; }
    }

從新運行程序:能夠看到成功了。
enter description here

咱們看看最終生成的數據庫:
enter description here

能夠看到生成的外鍵列就是咱們本身自定義的名稱了。 綜上所述:當兩個實體間有多個關係的時候,你能夠使用InverseProperty 特性和ForeignKey 特性來配置實體。

相關文章
相關標籤/搜索