Modeling
数据库模型映射即将CLR类映射到数据库架构,用于生成实体数据模型(EDM)模型。通常通过DBContext类重写OnModelCreate(DBModelBuilder)来配置模型。使用该对象注册构成的模型类型,并可通过将数据注释应用与类。调用该方法时将运行一组约定以发现初始模型,这些约定将自动发现模型的各个方面(如主键)且还将处理类上指定的任何数据注释。映射关系、属性的方式分为数据注解DataAnnotations特性和Fluent API函数。
在关系数据库中,表之间的关系是通过外键定义的用于在两个表的数据之间建立并强制链接的一列或列组合。常见的关系有三种:一对一关系(主键还用作外键两个表都没有单独的外键列、主键和外键都是单独的键)、一对多关系(外键在表示关系多端的表上定义)和多对多关系(涉及第三个表,主键来自两个相关联表的外键组成)
导航属性为在两个实体类型间导航关联提供了一种方式,使用导航属性可在两个方向上导航和管理关系,也可选择单向导航。如下标准创建
Including/Excluding Types (包含和不包含类型)
默认情况下在DBContext中设置的DBSet<T>对象模型都将映射到数据库中,但是也可在指定模型对象不持久化到数据库中。
DataAnnotations方式:NotMappedAttribut指示具有受支持数据类型
FluentAPI方式:指定不将CLR类型映射到数据库中的列
Including/Excluding Properties (包含和不包含属性)
默认情况下在模型对象中未标记特性的都将自动持久化到数据库中,除非使用特性将属性排除在外,则不会持久化到数据库中
l DataAnnotations方式:NotMappedAttribut指示具有受支持数据类型的每个属性都要在数据库中有表示
l FluentAPI方式:指定不将CLR属性映射到数据库中的列
Key Primary (主键)
主键是每个实体实例的唯一标识,当使用关系数据库映射时,还可以配置Alternate key作为唯一标识。
1) 单一主键
默认情况下EF会自动识别类中定义为”ID”或”Id”的属性;或类名后跟”ID”或”Id”。同时也可以指定非默认约定的主键。
l DataAnnotations方式:KeyAttribute表示一个或多个用于唯一标识实体的属性,实体框架必须要求有一个主键,若不指定则将引发异常
FluentAPI方式:指定将CLR属性映射到数据库中的列,使用HasKey方法,且可设置主键约束的名称,默认是PK_<type name> 返回
2) 组合主键
组合主键只能通过FluentAPI的方式配置如下:
Generated Properties (自动生成属性)
默认有三种模式用于自动生成属性值,分别是
a) No Value Generation:最普通的一种,必须赋予值才能持久化到数据库中
b) Value Generated to Add:默认赋值,即当未指定值时系统将自动为你赋值并持久化到数据库。
c) Value generated on add or update:当数据库中的一条记录被添加或更新,则将会生成一个值,用于记录信息
l DataAnnotations:DatabaseGeneratedAttribute 设定制定值来生成属性值
No Value Generation则采用DatabaseGenerated(DatabaseGeneratedOption.None)
Value Generated to Add则采用DatabaseGenerated(DatabaseGeneratedOption. Identity)
Value generated on add or update则采用DatabaseGenerated(DatabaseGeneratedOption. Computed)
l FluentAPI
No Value Generation
Value Generated to Add
Value generated on add or update
l 显式设置生成属性
在模型中通常有些属性可以根据系统的函数获得值(比如时间),该类生成属性就可以通过在配置函数中进行手动配置
如上EmployeeId按照约定是系统自动生成Identity,而EmploymentStared是根据录入信息时获取系统时间
当配置好后,在插入、编辑等操作实体时若是不显示指定生成属性值,则会自动获取系统预设值,当然也可以显示指定值。
Required/Optional Properties (必选和可选属性)
默认持久化数据模型中的属性若是允许为null则定义为可选属性(Optional),若不允许为null则定义为必选属性(Required),且默认情况下CLR中的类型都是允许为空的
l DataAnnotations: RequiredAttribute表示不为空的,必选的属性
l FluentAPI
Maximun/Minimun Length (最大值/最小值)
根据模型对象属性类型,如string,byte[]等类型设置存储的最大值和最小值
l DataAnnotations: MaxLengthAttribute设置最大值,MinLengthAttribute最小值
l FluentAPI:Name属性不应超过50个字符,若超过50个字符,则出现DBEntityValidationException异常。
Concurrency Tokens (并发令牌)
当模型对象中属性设置并发令牌,则在用户提交持久化时,EF将会检查该属性是否存在于时间相关问题,从而进行并发令牌的处理。当数据从数据库中加载时,EF会对标记的属性进行检查看是否有一个未提交更新或删除的值。
TimestampAttribute 表示时间戳,标识在每次数据库插入或更新时生成的一个值,它同样被用于并发令牌检查参考参数
l DataAnnotations:ConcurrencyCheckAttribute表示标记要在用户编辑或删除实体时用于在数据库中进行并发坚持的一个或多个属性
l FluentAPI
Inverse Property (逆向属性)
可以在主体和依赖体之间设置逆向属性用来关联两者
ReadOnly Property (只读属性)
标记为只读属性的模型对象属性,将不使用请求中的新值更新属性,通常只读属性时不做实体跟踪标记的,所以会使用AsNoTracking方法进行取消跟踪实体。
DataAnnotations:ReadonlyAttribute代表只读属性
Indexes (索引)
索引是一个数据存储中的公众概念,可加速根据列的查询,只能针对单一列设置索引
l FluentAPI:指定普通索引
指定索引为唯一性,代表不能有相同的属性值
可以指定多个列的索引
默认情况数据库中索引名称格式是IX_<type name>_<property name>,可以手动制定名称