目录

1.前言

2.约定

2.1 主键约定

2.2 关系约定

2.3 复杂类型约定

3.数据注释

3.1 主键

3.2 必需

3.3 MaxLength和MinLength

3.4 NotMapped

3.5 复杂属性

3.6 ConcurrencyCheck

4.Fluent API

5.总结

前言  

  在之前的Code First示例中,我们编写好代码直接运行,就自动会自定创建数据库,并且根据定义好的类创建了对应的表,更加神奇的时候竟然还能自动创建主键、外键等等。这是如何实现的呢?如果我们想指定特定的属性为主键又该如何实现呢? 

约定  

  其实Code First生成模型的时候会通过约定(Conventions)来检测,约定实际上是EF定义的一组规则集,用于在使用Code First时根据这些规则生成模型,是在System.Data.Entity.ModelConfiguration.Convertions命名空间中定义的,我们可以去扩展约定,当然也可以不是使用内置的约定。EF内置约定如下:

  

  从上图我们可以看到定义了复杂属性预定、外键预定、主键约定,当然还有很多很多,EF也一直扩充内置约定。

  

  主键约定  

  如果类的属性名为“ID”(不区分大小写)或者类名的后面跟有“ID”,则Code First会推断该属性是主键。如果主键属性的类型为数值或者GUID,则将其配置为标识列。

  

  如上图所示,DepartmentID会被约定为主键。

  关系约定  

  如果类A中的属性中包含他类B的属性(该属性在类B本身中约定为主键),并且类A中包含类B,则Code First会自动推断出关联关系,并确定外键。

  

  如上图所示,在DepartmentID在Course表中会定义为外键,并且Department表和Course表会自动建立关联关系。

  

  复杂类型约定

  当Code First无法推断出主键,并没有通过其他方式设置主键,则该类型会被自动当做复杂属性。对于以下类定义,Code First推断Details是复杂属性,因为它没有主键。

  

  更多参考:https://msdn.microsoft.com/zh-cn/library/jj679962(v=vs.113).aspx

数据注释  

  默认情况下,Code First会根据约定定义模型,但是默认的约定规则毕竟有限,Code First同样允许通过数据注释来定义模型,而且如果没有移除约定的话,会先通过约定定义,再通过数据注释来定义,那么数据注释是如何实现的呢?

  主键  

  类中需要通过数据注释来定义主键,非常简单,只需要在对应的属性上面加上KEY关键字,如下所示:

  

  必需  

  属性上面加上Requied关键字,说明这个属性是必需的,即不允许为空。

  

  MaxLength和MinLength  

  使用MaxLength和MinLength特性,可以限定字段的范围。

  

  上图定义BloggerName长度为5-10。

  NotMapped  

  不映射,顾名思义就是不会将类的属性映射到数据库表的字段上,标记了NotMapped特性不会在数据库表中生成对应的字段。

  

  复杂属性  

  在类名上面增加ComplexType特性,并且其他类中某属性为该类时,该类映射到数据时就会变成复杂属性。

  

  

  Blog类中添加一个属性为BlogDetails。

public BlogDetails BlogDetail { get; set; }

    

  ConcurrencyCheck  

  ConcurrencyCheck注释可用于标记要在用户编辑或删除实体时用于在数据库中进行并发检查的一个或多个属性。

    

  调用 SaveChanges 时,因为 BloggerName 字段上具有 ConcurrencyCheck 注释,所以在更新中将使用该属性的初始值。该命令将尝试通过同时依据键值和 BloggerName 的初始值进行筛选来查找正确的行。下面是发送到数据库的 UPDATE 命令的关键部分,在其中您可以看到该命令将更新 PrimaryTrackingKey 为 1 且 BloggerName 为“Julie”(这是从数据库中检索到该博客时的初始值)的行。

  

  如果在此期间有人更改了该博客的博主姓名,则此更新将失败,并引发 DbUpdateConcurrencyException 并且需要处理该异常。

  

  更多参考:https://msdn.microsoft.com/zh-cn/library/jj591583(v=vs.113).aspx

Fluent API  

  Code First模式下,默认行为是使用一组EF内嵌的约定规则将类映射到表。但有时候约定无法满足需求,这是我们还可以通过数据注释的方式来实现,但是数据注释功能仍然有限,好在EF提供了更加灵活的方式——Fluent API。

  Fluent API功能非常强大,它在通过重写DbContext上的OnModelCreating方法来实现自定义规则,可以设置主键、组合主键、外键、指定长度、指定属性是否映射到表等等。

  

  

  更多参考:https://msdn.microsoft.com/zh-cn/library/jj591617(v=vs.113).aspx

总结

  既然EF内置了很多约定规则,为何又可以通过数据注释方式来定义模型,而且还可以通过功能更加强大的Fluent API自定义模型。

  虽然内置的约定规则非常多,而且我想微软以后还会不断加入更多的约定,但是这些约定毕竟还是有限的,不能够满足所有用户需求,所以允许通过数据注释的方式来增加定义模型,但是有些情况通过数据注释依然是无法满足(例如:一个类型生成一张表还是多张表),这是我们可以通过Fluent API在生成模型之前自定义模型。

  综上所述,我们得知这三种定义模型的优先级为:约定—>数据注释—>Fluent API。

  

ORM系列之二:EF(4) 约定、注释、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. WPF技术触屏上的应用系列(二): 嵌入百度地图、API调用及结合本地数据库在地图上进行自定义标点的实现

    原文:WPF技术触屏上的应用系列(二): 嵌入百度地图.API调用及结合本地数据库在地图上进行自定义标点的实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系 ...

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

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

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

    EF Core中通过Fluent API完成对表的配置 设置实体在数据库中的表名 通过ToTable可以为数据模型在数据库中自定义表名,如果不配置,则表名为模型名的复数形式 public class ...

  5. ORM系列之二:EF(2)Code First

    目录 1. Code First是什么? 2. Code First 简单示例 3. 数据存储 4. 迁移 Code First是什么 Code First 顾名思义就是先写代码,当然不是乱写,而是按 ...

  6. ORM系列之二:EF(1)

    目录 1. EF是什么 2. 如何获取EF 3. EF有哪些主要模式 EF是什么 EF全称为Entity Framework,是微软推荐的一种数据库访问技术,属于重量级的ORM框架,功能非常强大,目前 ...

  7. ORM系列之二:EF(5) Model First

    前面我们已经介绍过EF中Code First开发模式,简而言之,就是不管三七二十一直接写代码,不过对于很多开发人员来说,可能并不习惯这样来开发,并且安装标准的开发流程,应该是先建模再进行编码,当然EF ...

  8. ORM系列之二:EF(3) 数据库连接

    目录 1.前言 2.Code First默认连接 3.Code First指定数据库 4.自定义连接 前言 在介绍EF的Code First模式时候,我们没有修改任何配置,运行之后自动在LocalDb ...

  9. java se系列(二) 关键字、注释、常量、进制转换、变量、数据类型转换、运算符

    1 关键字 1.1 关键字的概述 Java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名.方法名.类名.包名. 1.2 常见的关键字 备注 ...

随机推荐

  1. 快速得出e指数的算法

    , b, c = , d, e = , f[]; int main() { for (;b - c;) f[b++] = gap; , c;c-=, printf("%.4d ", ...

  2. tp5 中 model 的新增方法

    //默认主键为自动识别,如果需要指定,可以设置属性: namespace app\index\model; use think\Model; class User extends Model { pr ...

  3. SQL Server 2008 R2 企业版/开发版/标准版(中英文下载,带序列号)

    一. 简体中文 1. SQL Server 2008 R2 Developer (x86, x64, ia64) – DVD (Chinese-Simplified) File Name: cn_sq ...

  4. October 18th, Week 43rd Tuesday, 2016

    Live as if you were to die tomorrow. 将每一天都当作人生的最后一天来活. If I were to die tomorrow, I may choose to en ...

  5. IBatis和Hibernate区别

    1. 简介 Hibernate是当前最流行的O/R mapping框架.它出身于sf.net,现在已经成为Jboss的一部分了.iBATIS是另外一种优秀的O/R mapping框架,现已改名叫myB ...

  6. Android真机调试 Android.Util.AndroidRuntimeException: You cannot combine custom titles with other title features

    参考连接:http://blog.csdn.net/scyatcs/article/details/9003285 Android.Util.AndroidRuntimeException: You ...

  7. 【CentOS】正则表达式

    1.grep  [-cinvABC]  'word'  filename -c :打印符合要求的行数 --color:显示颜色 -i :忽略大小写(ignore) -n :在输出符合要求的行的同时连同 ...

  8. iOS Runtime学习笔记

    Associated Objects: @interface NSObject (AssociatedObject) @property (nonatomic, strong) id associat ...

  9. compass General 常用api学习[Sass和compass学习笔记]

    compass 中一些常用api 包括一些浏览器hack @import "compass/utilities/general" Clearfix Clearfix 是用来清除浮动 ...

  10. data Binding

    在WEEX中,我们使用{{}}双括号来对数据进行绑定,一旦我们对数据进行了绑定,当数据发生改变时,模板中的内容也会发生相应的改变. 如果绑定的数据是一个对象,里面有很多的内容,我们可以使用  .   ...