一对多(One-to-Many)关系:

下面,我们来介绍Code-First的一对多关系,比如,在一个Standard(年级)类中包含多个Student类。

如果想了解更多关于one-to-one,one-to-many,many-to-many关系的信息,请访问Entity Relationship

1.使用DataAnnotations配置One-to-Many关系:

如下代码所示:

public class Student
{
public Student() { } public int StudentId { get; set; }
public string StudentName { get; set; } public virtual Standard Standard { get; set; }
} public class Standard
{
public Standard()
{
Students = new List<Student>();
}
public int StandardId { get; set; }
public string Description { get; set; } public virtual ICollection<Student> Students { get; set; }
}

如上代码所示,Student实体类包含导航属性Standard,而且Standard实体类包含集合属性Student,这就是默认的一对多关系。

如果实体类遵循这种这种默认约定,也就是默认即是一对多关系了,我们就不需药额外的配置DataAnnotations或者Fluent API。

在数据库中,Code-First会通过在Student表中加入Standard_StandardId外键列来创建一对多关系。

我们建议在一个实体类中包含外键属性,如上代码中,如果在Student实体类中创建StandardId属性,它就会自动变成外键,因为它遵循了默认约定,即外键的格式应该为<类型名称>Id的格式。

同样的,如果我们创建的外键属性名字没有遵循默认的命名规定,那么我们就需要自己手动添加特性了,如下代码所示,Student类包含了一个StandardRefId属性:

public class Student
{
public Student() { } public int StudentId { get; set; }
public string StudentName { get; set; } public int StandardRefId { get; set; } [ForeignKey("StandardRefId")]
public virtual Standard Standard { get; set; }
} public class Standard
{
public Standard()
{
StudentsList = new List<Student>();
}
public int StandardId { get; set; }
public string Description { get; set; } public virtual ICollection<Student> Students { get; set; }
}

如果代码,我们必须要给Standard属性加上[ForeignKey("StandardRefId")]特性,这样创建数据库的时候才会将StandardRefId设置为外键,数据库如下:

2.使用Fluent API配置One-to-Many关系:

还是拿上面两个类的例子

Student类和Standard类代码如下:

public class Student
{
public Student(){ } public int StudentId { get; set; }
public string StudentName { get; set; } public int StandardId { get; set; } public virtual Standard Standard { get; set; }
} public class Standard
{
public Standard()
{
StudentsList = new List<Student>();
}
public int StandardId { get; set; }
public string Description { get; set; } public virtual ICollection<Student> Students { get; set; }
}

使用Fluent API配置一对多关系代码:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//one-to-many
modelBuilder.Entity<Student>()
.HasRequired<Standard>(s => s.Standard) // Student entity requires Standard
.WithMany(s => s.Students); // Standard entity includes many Students entities }

这是默认两个类的外键命名都遵循约定命名情况的时候,如果Student类包含了一个不遵循约定命名的外键名称呢,如下所示:

public class Student
{
public Student(){ } public int StudentId { get; set; }
public string StudentName { get; set; } //StdId有一个不同于Code-First默认约定命名的名称
public int StdId { get; set; } public virtual Standard Standard { get; set; }
} public class Standard
{
public Standard()
{
StudentsList = new List<Student>();
}
public int StandardId { get; set; }
public string Description { get; set; } public virtual ICollection<Student> Students { get; set; }
}

如上所示,StdId就没有遵循默认的<类型名称>Id的外键命名约定,所以我们的Fluent API配置如下:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//one-to-many
modelBuilder.Entity<Student>()
.HasRequired<Standard>(s => s.Standard)
.WithMany(s => s.Students)
.HasForeignKey(s => s.StdId); }

如你所见, modelBuilder.Entity<Student>().HasRequired<Standard>(s => s.Standard) 特别指定Student实体的Standard属性不能为空, .WithMany(s => s.Students).HasForeignKey(s => s.StdId) 指定了Standard实体包含多个Student实体,而且外键为StdId。

注意:每一个泛型方法都返回了一个该类型对象,所以才能有这种一串打点的写法^_^)

所以针对上面的配置代码,我们也可以以Standard类开头来写配置代码,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//configure one-to-many
modelBuilder.Entity<Standard>()
.HasMany<Student>(s => s.Students) //Standard has many Students
.WithRequired(s => s.Standard) //Student require one Standard
.HasForeignKey(s => s.StdId);//Student includes specified foreignkey property name for Standard
}

代码运行后将会创建如下的数据库:

注意StdId是不为空的列,所以每次加入和更新Students表的时候必须要指定Student实体类的Standard属性。

在One-to-Many关系中配置可空外键:

很简单,使用HasOptional方法代替HasRequired方法即可。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//one-to-many
modelBuilder.Entity<Student>()
.HasOptional<Standard>(s => s.Standard)
.WithMany(s => s.Students)
.HasForeignKey(s => s.StdId); }

这样,Students表的StdId列就可为空了。


最近太忙了,工作上,生活上,总之,好事多磨吧,既然下定决心了要更下去,就不能食言。今天就先到这里吧,下篇将讲多对多关系的操作。

EntityFramework Code-First 简易教程(九)-------一对多的更多相关文章

  1. WebGL简易教程(九):综合实例:地形的绘制

    目录 1. 概述 2. 实例 2.1. TerrainViewer.html 2.2. TerrainViewer.js 3. 结果 4. 参考 1. 概述 在上一篇教程<WebGL简易教程(八 ...

  2. Entity Frame Code First 简易教程

    简介 什么是ORM 搭建Entity FrameWork CodeFirst应用 数据库迁移 表属性常见配置 Entity FrameWork 一对多.多对多 一.简介 Entity Framewor ...

  3. WebGL简易教程(十):光照

    目录 1. 概述 2. 原理 2.1. 光源类型 2.2. 反射类型 2.2.1. 环境反射(enviroment/ambient reflection) 2.2.2. 漫反射(diffuse ref ...

  4. WebGL简易教程(十一):纹理

    目录 1. 概述 2. 实例 2.1. 准备纹理 2.2. 配置纹理 2.3. 使用纹理 3. 结果 4. 参考 1. 概述 在之前的之前的教程<WebGL简易教程(九):综合实例:地形的绘制& ...

  5. WebGL简易教程——目录

    目录 1. 绪论 2. 目录 3. 资源 1. 绪论 最近研究WebGL,看了<WebGL编程指南>这本书,结合自己的专业知识写的一系列教程.之前在看OpenGL/WebGL的时候总是感觉 ...

  6. Android实战简易教程-第三十九枪(第三方短信验证平台Mob和验证码自己主动填入功能结合实例)

    用户注冊或者找回password时通常会用到短信验证功能.这里我们使用第三方的短信平台进行验证实例. 我们用到第三方短信验证平台是Mob,地址为:http://mob.com/ 一.注冊用户.获取SD ...

  7. CURL (CommandLine Uniform Resource Locator) 简易教程!

    1 http://curl.haxx.se/ http://curl.haxx.se/docs/httpscripting.html curl is an open source command li ...

  8. CRL快速开发框架系列教程九(导入/导出数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. JavaScript简易教程(转)

    原文:http://www.cnblogs.com/yanhaijing/p/3685304.html 这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScri ...

  10. 文件上传利器SWFUpload入门简易教程

    凡做过网站开发的都应该知道表单file的确鸡肋. Ajax解决了不刷新页面提交表单,但是却没有解决文件上传不刷新页面,当然也有其它技术让不刷新页面而提交文件,该技术主要是利用隐藏的iFrame, 较A ...

随机推荐

  1. Centos 7 安装 rabbitmq

    1.安装erlang rabbitmq 官方下载地址 "http://www.rabbitmq.com/download.html" ,选择"RHEL, CentOS, ...

  2. Spring Boot + Spring Cloud 构建微服务系统(二):服务消费和负载(Ribbon)

    使用RestTemplate调用服务 在上一篇教程中,我们是这样调用服务的,先通过 LoadBalancerClient 选取出对应的服务,然后使用 RestTemplate 进行远程调用. Load ...

  3. 逆向知识之CS1.6辅助/外挂专题.1.实现CS1.6主武器副武器无限子弹

    逆向知识之CS辅助/外挂专题.1.实现CS主武器副武器无限子弹 PS: 相信大家CS1.6这类的FPS应该玩过.现在我们通过外挂手法.讲解逆向的本质.以及应用. 关于CS1.6的下载.网络百度下载即可 ...

  4. SpringBoot学习(一)—— web项目基础搭建

    首先我们在浏览器打开这个网站 https://start.spring.io/ 打开后可以看到以下页面 在这里我们可以快速搭建一个SpringBoot基础项目,填写和选择完相应的信息后,我们点击那个绿 ...

  5. JavaWeb学习(二十二)———EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  6. Xshell6设置字体大小

    Xshell可以远程连接到linux服务器,但有时终端字体太小,可以按照如下步骤修改字体大小: 菜单栏: 文件-属性-外观,修改字体大小后点击确定即可(也可以使用ALT+P快捷键打开属性).

  7. MySQL多表查询练习题

    一.准备数据 #创建表及插入记录 CREATE TABLE class ( cid ) NOT NULL AUTO_INCREMENT, caption ) NOT NULL, PRIMARY KEY ...

  8. Extjs4---Cannot read property 'addCls' of null 或者 el is null 关于tab关闭后再打开不显示或者报错

    做后台管理系统时遇到的问题,关于tab关闭后再打开不显示,或者报错 我在新的tabpanel中加入了一个grid,当我关闭再次打开就会报错Cannot read property 'addCls' o ...

  9. 【原】PHP从入门到精通2小时【图文并茂】

    原创内容,转载请注明. 主要内容: 搭建PHP开发环境 第一个helloworld程序 变量 全局变量 循环结构 函数 数组 面向对象编程 继承 接口 多态 日志 文件的读写 时间格式和时区 创建图形 ...

  10. http请求的headers详解

    关于http请求的headers详解:这里以HTTP1.1为例结合postman返回的信息 1.Server →nginx/1.15.8   A name for the server  这是post ...