数据对象的映射关系

上图是一个以用户信息为中心的实体关系图,关系说明如下:

一个用户可拥有一个可选的用户扩展信息(1 – 0)
一个用户扩展信息拥有一个必需的所属用户信息(0 – 1)
一个用户扩展信息拥有一个用户地址信息(复合类型)
一个用户可对应多个登录日志信息(1 – N)
一个登录日志拥有一个必需的所属用户信息(N- 1)
一个用户可以拥有多个角色(N – N)
一个角色可以分配给多个用户(N – N)

下面来依依看一下这几种数据表的关系

第一种:0:1。举例说明:有一个数据表Emplyee代表该公司的员工表,而该公司里的员工有一个通讯账号数据库表MessagingAccount,而有些员工不使用,也就是没有通讯账号。这就说明员工Employee和MessagingAccount之间的关系就是一个员工对应一个通讯账号,或者一个员工没有通讯账号。

WithOptional:将关系配置为required:optional。(required:0…1端的1,表示必需,不可为null;optional:0…1端的0,表示可选,可为null。下同)

第二种:1:1.举例说明:还是第一种的例子中每个员工都有一个通讯账号的话。

WithRequiredDependent:将关系配置为required:required。要配置的实体类型将成为依赖对象,且包含主体的外键。作为关系目标的实体类型将成为关系中的主体。

modelBuilder.Entity<Employee>().HasRequired(emp => emp.Acount).WithRequiredPrincipal(a => a.Employee);

第三种:1:N。举例说明:订单和谁下的订单。通常的关系都是一个订单只会由一个人来下,反过来也就是说一个人可能有多个订单。也就是一个Customer可以有多个Order.是一个一对多的关系。

modelBuilder.Entity<Order>().HasRequired(o=>o.Customer).WithMany();

第四种:N:N。举例说明:订单和产品之间的关系。一个Order订单可能会有多个产品Product的可能。同理,一个产品Product也会存在与多个订单Order当中。

modelBuilder.Entity<Order>().HasMany(o => o.Products).WithMany(p => p.Orders).Map(m =>

{

m.ToTable("OrderDetails");

m.MapLeftKey("OrderID");

m.MapRightKey("ProductID");

});

配置多对多的关系,并指定了表名、对应的外键;注意如果不使用FluentAPI配置,Product和Order配置了相应的导航属性,EF也会默认生成一张表(表名为“<数据类1>+<数据类2>”)

DataAnnotation

KeyAttribute:对应数据库中的主键
RequiredAttribute:对应数据库中字段的数据是否可以为null
MaxLengthAttribute:对应数据库中字符串类型字段的最大长度
MinLengthAttribute:在数据库中无对应,但在代码中字符串最小长度
ConcurrencyCheckAttribute:指定用于开放式并发检查的列的数据类型
TimestampAttribute:将列的数据类型指定为行版本

System.ComponentModel.DataAnnotations命名空间中只定义了部分实体验证的特性,在EntityFramework程序集中定义了更多的数据映射特性:

DatabaseGeneratedAttribute:标记指定实体属性是由数据库生成的,并指定生成策略(None数据库不生成值,Identity当插入行时,数据库生成值,Computed当插入或更新行时,数据库生成值)
ColumnAttribute:指定实体属性在数据库中的列名及数据类型
TableAttribute:指定实体类对应的数据表名
ForeignKeyAttribute:指定导航属性的外键字段
NotMappedAttribute:标记指定实体属性在创建数据库中不创建对应字段
ComplexTypeAttribute:标记指定实体属性是将一个对象作为另一个对象的属性,映射到数据库中则子对象表现为多个属性字段

Fluent API

System.ComponentModel.DataAnnotations命名空间的DataAnnotation在EntityFramework程序集中也有相应的API:

HasKey – KeyAttribute:配置此实体类型的主键属性
IsRequired – RequiredAttribute:将此属性配置为必需属性。用于存储此属性的数据库列将不可以为null
HasMaxLength – MaxLengthAttribute:将属性配置为具有指定的最大长度
IsConcurrencyToken – ConcurrencyCheckAttribute:将属性配置为用作开放式并发标记
IsRowVersion – TimestampAttribute:将属性配置为数据库中的行版本。实际数据类型将因使用的数据库提供程序而异。将属性设置为行版本会自动将属性配置为开放式并发标记。

ToTable – TableAttribute:配置此实体类型映射到的表名
HasColumnName – ColumnAttribute:配置用于存储属性的数据库列的名称
HasForeignKey – ForeignKeyAttribute:将关系配置为使用在对象模型中的外键属性。如果未在对象模型中公开外键属性,则使用Map方法
Ignore – NotMappedAttribute:从模型中排队某个属性,使该属性不会映射到数据库
HasRequired:通过此实体类型配置必需关系。除非指定此关系,否则实体类型的实例将无法保存到数据库。数据库中的外键不可为null。
HasOptional:从此实体类型配置可选关系。实体类型的实例将能保存到数据库,而无需指定此关系。数据库中的外键可为null。
HasMany:从此实体类型配置一对多关系。
WithOptional:将关系配置为required:optional。(required:0…1端的1,表示必需,不可为null;optional:0…1端的0,表示可选,可为null。下同
WithOptionalDependent:将关系配置为optional:optional。要配置的实体类型将成为依赖对象,且包含主体的外键。作为关系目标的实体类型将成为关系中的主体。
WithOptionalPrincipal:将关系配置为optional:optional。要配置的实体类型将成为关系中的主体。作为关系目标的实体类型将成为依赖对象,且包含主体的外键。
WithRequired:将关系的指定端配置为必需的,且在关系的另一端有导航属性。
WithRequiredDependent:将关系配置为required:required。要配置的实体类型将成为依赖对象,且包含主体的外键。作为关系目标的实体类型将成为关系中的主体。
WithRequiredPrincipal:将关系配置为required:required。要配置的实体类型将成为关系中的实体。作为关系目标的实体类型将成为依赖对象,且包含主体的外键。
WillCascadeOnDelete:配置是否对关系启用级联删除。
Map:将关系配置为使用未在对象模型中公开的外键属性。可通过指定配置操作来自定义列和表。如果指定了空的配置操作,则约定将生成列名。如果在对象模型中公开了外键属性,则使用 HasForeignKey 方法。并非所有关系都支持在对象模型中公开外键属性。
MapKey:配置外键的列名。
ToTable:配置外键列所在表的名称和架构。

经常用到的DataAnnotation与FluentAPI列举完了,使用上还是遵守这个原则:

如果在System.ComponentModel.DataAnnotations命名空间存在相应的标签,就使用 DataAnnotation 的方式,如果不存在,则使用 FluentAPI 的方式。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平