EF Core中通过Fluent API完成对表的配置

设置实体在数据库中的表名

通过ToTable可以为数据模型在数据库中自定义表名,如果不配置,则表名为模型名的复数形式

public class EmployeeConfig:IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
// 默认情况下,Employee实体在数据库中会生成Employees的数据表,这里通过ToTable(),将其指定为Employee
builder.ToTable("Employee");
}
}

表间关系映射

在EF Core中,通过Fluent API做表间关系映射时,可以将API分为两类两种

两类:has和with

三种:One、Many

通过两类两种的组合,就可以完成绝大多数表间关系的映射,下面放一些常用的关系配置

public class EmployeeConfig:IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
builder.ToTable(nameof(Employee));
// 配置Employee表有一个Department对象,Department有多个Employee对象
// 这是典型的一对多配置
builder.HasOne(e => e.Department).WithMany(d=>d.Employees);
}
}

通常配置一对多的时候只需要在一张表上进行配置就可以了,但也可以在两张表上都进行配置,这样更清晰

public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
builder.ToTable(nameof(Department)); // 配置Department表有多个Employee对象,Employee有一个Department对象
builder.HasMany(d => d.Employees).WithOne(e=>e.Department); // 配置Department表有一个领导(也是Employee对象),领导也属于一个部门
builder.HasOne(d => d.Leader).WithOne(e => e.Department);
}
}

在表关系的配置中,遵循 Has…( ).With…( )的配置方式,Has指的是配置的这张表,然后通过lambda表达式来指定对应的属性,如上面的Department表,通过lambda表达式 d => d.Employees 指定要配置的字段是Employess,HasMany则是指Department表的Employees对应多个

With则是前面has指定的属性对应的表,WithOne反过来指定了Employee表中的Department字段是一个

所以这里就是一个多对一的配置

通过这四个单词的组合,就可以完成一对多、一对一、多对多(通过中间表拆分成两个一对多)的表间关系配置

这里将Entity文件放出来,以便更好理解

public class Employee
{
public Guid Id { get; set; }
public string Name { get; set; }
public bool Gender { get; set; }
public string Phone { get; set; }
public decimal Rating { get; set; }
public decimal Salary { get; set; }
public Guid DepartmentId { get; set; }
public Department Department { get; set; }
} public class Department
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid LeaderId { get; set; }
public Employee Leader { get; set; }
public List<Employee> Employees { get; set; }
public string NoUse { get; set; }
}

主键设置

EF Core会自动将实体中名为Id的属性设置为主键,但是有时候主键并不是这么规整的命名,或者需要联合主键的情况,就需要手动指定主键

public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
// 配置数据库中主键为实体的Id字段
builder.HasKey(d => d.Id);
}
}

这里指定了Department的Id字段为主键,实体属性名为Id不用手动指定,这里只是展示一下自定义的语法

public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
// 配置数据库中主键为实体的Id和Name的联合主键
builder.HasKey(d => new {d.Id, d.Name});
}
}

联合主键的设置也很简单,通过new一个匿名对象的方式提供

主键的值

EF Core会默认为主键生成值,但有时候我们希望使用主键并且自己自定义相关的值,比如说自选账号、课程Id等,这时可以这样配置

public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
builder.Property(d => d.Id)
.ValueGeneratedNever(); // 配置数据库中实体的Id字段不自动生成值
}
}

通过ValueGeneratedNever()可以禁用自动生成值,实际上它可以给任何一个属性都配置,但是通常只有主键是默认生成值的

外键设置

如果有外键则必须有另一个与之关联的表,所以外键配置只能在表关系配置后附加

EF Core会默认将关联表+Id的字段设置为外键,同主键一样,有时候不是那么规整,就需要手动指定

public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
builder.HasOne(d => d.Leader).WithOne(e => e.Department).HasForeignKey("LeaderId");
}
}

在Department实体中指定了Leader,Leader也是Employee对象,如果依照约定属性为EmployeeId会自定设置为外键字段,但是这里指定了LeaderId,就需要手动设置外键字段为LeaderId

忽略某个字段在数据库中的映射

public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
// 数据库中忽略该字段,该字段不会存在该实体属性对应的字段
builder.Ignore(d => d.NoUse);
}
}

前面Department实体中有一个NoUse字段,但是不希望它在数据库中映射该字段,就可以通过Ignore的方式忽略掉

字段约束

通过Fluent API能够对字段进行约束,这样在生成数据库表时就会将相应的约束生成,如设置了字段的最大长度在数据库表中的字段数据类型时nvarchar(设定的最大长度),如果没有设置,在数据库表中的字段数据类型则是nvarchar(max)

Fluent支持流式语法,可以将多个约定流式附加

非空约束
public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
// 设置姓名字段不为空
builder.Property(d => d.Name).IsRequired();
}
}
字段最大长度
public class DepartmentConfig:IEntityTypeConfiguration<Department>
{
public void Configure(EntityTypeBuilder<Department> builder)
{
// 设置姓名字段最大长度为30,且不为空
builder.Property(d => d.Name).HasMaxLength(30).IsRequired();
}
}
固定长度字段
public class EmployeeConfig:IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
// Phone字段在数据库中为11位固定长度字符串 IsFixedLength()用于指定该字段是否为固定长度
builder.Property(e => e.Phone).HasMaxLength(11).IsFixedLength();
}
}

IsFixedLength()用于指定该字段是否为固定长度,其长度为前面设置的字段最大长度

指定字段名
public class EmployeeConfig:IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
// 显式指定实体属性对应数据库中的字段名,这里指定Phone字段对应的数据库字段为ChinaPhone
builder.Property(e => e.Phone).HasColumnName("ChinaPhone");
}
}
指定数据类型
public class EmployeeConfig:IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
// 指定decimal的精度为5刻度为2
builder.Property(e => e.Rating).HasColumnType("decimal(5, 2)");
}
}

注:关于精度和刻度的解释,精度是数字的位数,刻度是小数的位数,即decimal(5, 2)能表示的最大数是999.99,一共五位,小数两位

指定数据类型更常用的情况是将实体的decimal类型指定为数据库中的money类型

public class EmployeeConfig:IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
// 指定decimal的精度为5刻度为2
builder.Property(e => e.Salary).HasColumnType("money");
}
}

为什么我的Fluent API配置长这样

因为进行了分组配置,将每个类的配置分别拆分到不同的文件

具体的配置可以看看微软的官方文档

分组配置

EF Core中通过Fluent API完成对表的配置的更多相关文章

  1. 10.翻译系列:EF 6中的Fluent API配置【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/fluent-api-in-code-first.aspx EF 6 Code-Firs ...

  2. 9.翻译系列:EF 6以及EF Core中的数据注解特性(EF 6 Code-First系列)

    原文地址:http://www.entityframeworktutorial.net/code-first/dataannotation-in-code-first.aspx EF 6 Code-F ...

  3. 9.4 翻译系列:EF 6以及 EF Core中的NotMapped特性(EF 6 Code-First系列)

    原文链接:http://www.entityframeworktutorial.net/code-first/notmapped-dataannotations-attribute-in-code-f ...

  4. EF Core中的DB First与Code First

    前言: 大家都习惯在程序中生成对应的model来对数据库进行操作,所以如何快速的生成数据库表的对应model,是基础之一.总结了一下在我的认知中大概是这个结构: Db first方式: 先创建好对应的 ...

  5. 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...

  6. EF Core中避免贫血模型的三种行之有效的方法(翻译)

    Paul Hiles: 3 ways to avoid an anemic domain model in EF Core 1.引言 在使用ORM中(比如Entity Framework)贫血领域模型 ...

  7. EF Core 中多次从数据库查询实体数据,DbContext跟踪实体的情况

    使用EF Core时,如果多次从数据库中查询一个表的同一行数据,DbContext中跟踪(track)的实体到底有几个呢?我们下面就分情况讨论下. 数据库 首先我们的数据库中有一个Person表,其建 ...

  8. EF Core中如何正确地设置两张表之间的关联关系

    数据库 假设现在我们在SQL Server数据库中有下面两张表: Person表,代表的是一个人: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ...

  9. Entity Framework 实体框架的形成之旅--Code First模式中使用 Fluent API 配置(6)

    在前面的随笔<Entity Framework 实体框架的形成之旅--Code First的框架设计(5)>里介绍了基于Code First模式的实体框架的经验,这种方式自动处理出来的模式 ...

随机推荐

  1. Codeforces Round #651 (Div. 2) A Maximum GCD、B GCD Compression、C Number Game、D Odd-Even Subsequence

    A. Maximum GCD 题意: t组输入,然后输入一个n,让你在区间[1,n]之间找出来两个不相等的数a,b.求出来gcd(a,b)(也就是a,b最大公约数).让你求出来最大的gcd(a,b)是 ...

  2. Codeforces Round #481 (Div. 3) C. Letters (模拟,二分)

    题意:有个\(n\)个公寓,每个公寓\(a_{i}\)代表着编号为\(1-a_{i}\)个房间,给你房间号,问它在第几栋公寓的第几个房间. 题解:对每个公寓的房间号记一个前缀和,二分查找属于第几个公寓 ...

  3. Win10 资源管理器经常卡死问题

    什么问题? 我的Win10资源管理器开始出现卡死(假死.未响应)的情况,频率越来越高,触发方式越来越广,包括OpenDialog.打开拥有快捷方式的文件夹/桌面.右键空白处.右键文件/文件夹.拖动文件 ...

  4. MySQL菜鸟实录(一):MySQL服务安装实战

    CentOS 7 基本信息 系统版本: CentOS 7.3 64bit 系统配置: 4vCPUs | 8GB 磁盘空间: [root@ecs-ce5a-0001 ~]# df -h Filesyst ...

  5. Java 在Word中添加多行图片水印

    Word中设置水印效果时,不论是文本水印或者是图片水印都只能添加单个文字或者图片到Word页面,效果比较单一,本文通过Java代码示例介绍如何在页面中添加多行图片水印效果,即水印效果以多个图片平铺到页 ...

  6. 在kubernetes集群里集成Apollo配置中心(6)之实战使用apollo分环境管理dubbo服务

    生产实践 1.迭代新需求/修复BUG(编码--->提git) 2.测试环境发版,测试(应用通过编译打包发布至test命名空间) 3.测试通过,上线(应用镜像直接发布至prod命名空间) 系统架构 ...

  7. 国内centos/windows10安装minikube

    centos/windows10安装minikube 目录 centos/windows10安装minikube A win10安装minikube 1 下载安装kubectl.exe 1.1 准备目 ...

  8. meterpreter php payload && windows payload 学习

    一 情景 本地kali linux 192.168.1.2 目标 windows NT 服务器192.168.1.4 目的是获取shell 二 过程 首先在linux建立终端 ,msfconsole ...

  9. 关于FFT的一些理解,以及如何手工计算FFT加深理解和验证正确性

    总结缺少逻辑性和系统性,主要便于自己理解和记忆 关于一维FFT的 于是复系数Cn是图像傅里叶变换的yn列向量 于是我们看到最后引入,Cn这个复系数的模来表征频率波的振幅记为Sn(即简谐波叠加的数量 然 ...

  10. Linux 驱动框架---linux 设备

    Linux 设备 Linux驱动中的三大主要基础成员主要是设备,总线和驱动.今天先来从设备开始分析先把设备相关的数据结构放到这里方便后面看到来查,其中有些进行了简单的注释. struct device ...