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


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

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

當兩個實體之間不止一種關系的時候,可以使用InverseProperty特性,為了理解InverseProperty特性我們來做一個例子:
1.創建一個控制台應用程序,安裝好EF:
enter description here
2.創建Course類:

 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類:

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鏈接字符串:

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

5.測試代碼:

 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

現在假設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類:

 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 特性來配置實體。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM