欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

程序员文章站 2022-07-04 23:28:58
原文链接:https://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx 当两个实体之间不止一种关系的时候,可以使用InversePrope ......

原文链接:

当两个实体之间不止一种关系的时候,可以使用inverseproperty特性,为了理解inverseproperty特性我们来做一个例子:
1.创建一个控制台应用程序,安装好ef:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】
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.运行程序:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】
可以看到,根据默认的约定,生成的数据库如下:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

现在假设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.
删掉之前生成的数据库后,我们运行一下程序:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】
看看生成的数据库:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】
看到,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两个外键。
然后在删除数据库,重新运行一下程序:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

看一下生成的数据库:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

可以看到现在生成的数据库就是正确的了。
进一步配置,你可以使用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类中添加两个属性列,配置外键,现在删除数据库,重新运行一下:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】
看到报错了,我们修改一下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; }
    }

重新运行程序:可以看到成功了。
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

我们看看最终生成的数据库:
9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

可以看到生成的外键列就是我们自己自定义的名称了。
综上所述:当两个实体间有多个关系的时候,你可以使用inverseproperty 特性和foreignkey 特性来配置实体。