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注释可用于标记要在用户编辑或删除实体时用于在数据库中进行并发检查的一个或多个属性。