EF6基础系列(五)---EF中的实体关系

这一节将总结EF是怎么管理实体之间的关系。
EF与数据库一样支持三种关系类型:①一对一 ,②一对多,③多对多。

下边是一个SchoolDB数据库的实体数据模型,图中包含所有的实体和各个实体间的关系。通过设计器我们很容易看出实体间的对应关系

1.一对一

如上图,Student和StudentAddress具有一对一的关系(零或一)。一个学生只能有一个或零个地址。实体框架将Student实体导航属性添加到StudentAddress实体中,将StudentAddress实体导航属性添加到Student实体中。同时,StudentAddress类中将StudentId作为PrimaryKey和ForeignKey属性,这样Student和StudentAddress就成为一对一的关系。

public partial class Student
{
    public Student()
    {
        this.Courses = new HashSet<Course>();
    }

    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public Nullable<int> StandardId { get; set; }
    public byte[] RowVersion { get; set; }
    //实体导航属性
    public virtual StudentAddress StudentAddress { get; set; }
    }

public partial class StudentAddress
{
  //同时是主键和外键
    public int StudentID { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    //实体导航属性
    public virtual Student Student { get; set; }
}

在上面的示例中,StudentId属性在StudentAddress类中是同时是PrimaryKey和ForeignKey。我们可以在context的OnModelCreating方法中使用Fluent API进行配置。

2.一对多

Standard与Teacher实体具一对多的关系。这表示多个教师可以处在一个级别,而每个教师只能有一个级别。

public partial class Standard
{
    public Standard()
    {
        this.Teachers = new HashSet<Teacher>();
    }

    public int StandardId { get; set; }
    public string StandardName { get; set; }
    public string Description { get; set; }
    //集合导航属性
    public virtual ICollection<Teacher> Teachers { get; set; }
}

public partial class Teacher
{
    public Teacher()
    {
        this.Courses = new HashSet<Course>();
    }
    public int TeacherId { get; set; }
    public string TeacherName { get; set; }
    public Nullable<int> TeacherType { get; set; }
    //外键
    public Nullable<int> StandardId { get; set; }
    //实体导航属性
    public virtual Standard Standard { get; set; }
}

Standard实体具有集合导航属性 Teachers (请注意它是复数),这表明Standard可以有一个教师集合(许多教师)。而Teacher实体具有Standard实体导航属性,表明Teacher只有一个相关联Standard,同时Teacher中包含StandardId外键。这样Standard与Teacher就成为了一对多的关系。

3.多对多关系

Student和Course具有多到多关系。这表示一个学生可以参加许多课程,而一个课程也可以向许多学生讲授。
数据库包括StudentCourse中间表,表中只包含Student和Course的主键。
如上图所示,Student实体包含集合导航属性 Courses,Course实体包含集合导航属性 Students以表示它们之间的多对多关系。这两个表都没有外键关系,它们通过StudentCourse中间表进行关联。

下面的代码片段展示了Student和Course实体类。

public partial class Student
{
    public Student()
    {
        this.Courses = new HashSet<Course>();
    }

    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public Nullable<int> StandardId { get; set; }
    public byte[] RowVersion { get; set; }
    //集合导航属性
    public virtual ICollection<Course> Courses { get; set; }
}

public partial class Course
{
    public Course()
    {
        this.Students = new HashSet<Student>();
    }

    public int CourseId { get; set; }
    public string CourseName { get; set; }
     //集合导航属性
    public virtual ICollection<Student> Students { get; set; }
}

注:实体框架在中间表仅有两个表的主键(只有StudentId和CourseId)时才自动维护多对多关系。当我们给Student添加一个Course或给Course添加一个Student,执行SaveChange()时,EF会在中间表自动会插入对应的StudentId和CourseId。如果中间表包含其他列,那么EDM也会为中间表创建实体,EF不再自动维护中间表,那么我们就需要手动管理多对多实体的CRUD操作。

原文地址:https://www.cnblogs.com/wyy1234/p/9627676.html

时间: 2024-07-31 16:19:20

EF6基础系列(五)---EF中的实体关系的相关文章

EF6基础系列(九)--- 附加离线实体图集到上下文

附加离线实体图集到上下文 这节主要内容是通过不同的方法将离线实体附加到上下文中. 在离线场景中,保存一个实体要略微困难一些.当我们保存一个离线的实体图集或一个单独的离线实体时,我们需要做两件事.首先,我们要把实体附加到新的上下文中,让上下文了知道存在这些实体.其次,我们需要手动设置每个实体的EntityState,因为新的上下文不知道这些离线实体都经过了些什么操作,所以新的上下文不能自动地给实体添加EntityState. 下图说明了此过程. 为了将离线实体附加到上下文,并为实体图中的每个实体设

【C++自我精讲】基础系列五 隐式转换和显示转换

0 前言 1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换. 2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换. 1 隐式转换 定义:隐式转换是系统跟据程序的需要而自动转换的. 1)C++类型(char,int,float,long,double等)的隐式转换: 算术表达式隐式转换顺序为: 1.char - int - long - double 2.float - double //1)算术表达式 int m = 10; double n = m;//n = 10

EF6基础系列(十一)---EF6中的异步查询和异步保存

EF6中的异步查询和异步保存 在.NET4.5中介绍了异步操作,异步操作在EF中也很有用,在EF6中我们可以使用DbContext的实例进行异步查询和异步保存. 1.异步查询 下边是一个通过L2E语法实现异步查询的栗子: private static async Task<Student> GetStudent() { Student student = null; using (var context = new SchoolDBEntities()) { Console.WriteLine

EF6基础系列(十)---离线场景保存实体和实体图集

离线场景保存和删除实体/实体图集 这一节的内容是在离线场景中保存实体和实体图集 在离线场景中,当我们保存一个离线的实体图集或一个单独的离线实体时,我们需要做两件事.首先,我们要把实体附加到新的上下文中,让上下文了知道存在这些实体.其次,我们需要手动设置每个实体的EntityState,因为新的上下文不知道这些离线实体都经过了些什么操作,所以新的上下文不能自动地给实体添加EntityState.上一节我们清楚了附加离线图集的方法,附加离线图集时默认添加的EntityState不一定合适,所以我们就

ADO.NET EF 中的实体修改方法

http://www.cnblogs.com/zfz15011/archive/2010/05/30/1747486.html 1.传统修改模式,看下列代码 using (NorthwindEntities context = new NorthwindEntities()){    Region region = context.Region.FirstOrDefault(v => v.RegionID == 4);    region.RegionDescription = "Test

WebApi学习笔记09:OData中的实体关系

1.概述 本例是在学习系列07介绍的项目基础上进行演练…… 2.添加实体 在Models文件夹下,添加Supplier.cs类,代码: using System.Collections.Generic; namespace ProductService.Models { public class Supplier { public int Id { get; set; } public string Name { get; set; } public ICollection<Product>

EF中的实体类型(EF基础系列篇6)

EF中有两种类型的实体:POCO Entity和dynamic proxy entity. POCO Entity (Plain Old CLR Object) POCO class是一个类,它不依赖任何.NET framework的基类,它就像任何其他的普通类一样,这也是为什么被称之为“Plain Old CLR Object”的原因: 这些由实体数据模型生成的POCO实体支持大多数的增删查改的功能.下面是一个Studnet POCO实体: public class Student { pub

EF6基础系列(12)--- EF进行批量添加/删除

EF6添加了批量添加/删除实体集合的方法,我们可以使用DbSet.AddRange()方法将实体集合添加到上下文,同时实体集合中的每一个实体的状态都标记为Added,在执行SaveChange()方法时为每个实体执行Insert操作:同样的我们使用DbSet.RemoveRange()方法将集合中的所有实体都标记为deleted状态,在执行SaveChange()方法时为每一条数据执行delete操作. 通过AddRange()和RemoveRange()方法可以有效提升性能,所以建议在进行不批

MVC3+EF4.1学习系列(五)----- EF查找导航属性的几种方式

通过上一篇的学习 我们把demo的各种关系终于搭建里起来 以及处理好了如何映射到数据库等问题 但是 只是搭建好了关系 问题还远没有解决 这篇就来写如何查找导航属性 和查找导航属性的几种方式 已经跟踪生成的SQL来检测是否满意 通过这节学习 来明白什么时候用哪个~~ 一.三种加载 1.延迟加载 这是原文中的图 大家可以去看下  我模仿上面的做了个测试  出现了  已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭. 我的解决办法是    var departments