令人心动的特性,建模3.0的全新实体服务
简介
以前平台提供的实体服务只能满足单表的增删改查,不能按照建模中实体的关系来进行关联查询,如果表与表之间存在关联关系,进行数据的新增时还要手动的维护关联表的外键信息,这样不仅不方便而且还很容易出错,所以为了解决实体之间的关联查询以及实体之间关系的自动映射,在运行平台中引入 EntityFramework Core,重新设计新的实体服务。
使用场景
有3个元数据分别是,合同(Contract)、合同详情(ContractDetail)、合同详情附件(ContractDetailAttachment),其中合同与合同详情在建模中是一对一的关系,合同详情与合同详情附件是一对多的关系,下面通过简单的实例来实现对合同、合同详情、合同详情附件的新增、修改和查询。
定义实体
1、新增实体元数据,由于新版的实体服务是以建模平台的实体元数据为准,也就是说业务中使用的实体要在实体元数据中必须存在,所以首先我们新建实体元数据,如图:新建了3个实体元数据,分别是 合同(Contract),合同详情(ContractDetail),合同详情附件(ContractDetailAttachment)。
2、新增实体关系,其中合同与合同详情是一对一的关系,通过合同主键(ContractGUID)关联,合同详情与合同详情附件是一对多的关系通过合同详情主键(ContractDetailGUID)关联,所以在建模平台的对象关系中还要新建三者之间的关系,如图:
平台支持实体元数据配置了默认值的场景,如下:
3、在代码中新增 ContractEntity、ContractDetailEntity、ContractDetailAttachmentEntity 类,分别对应合同、合同详情、合同详情附件这三个实体元数据,实体类型建议以 Entity 结尾。
平台规范:
1. 实体必须是抽象类型的并且继承于 Mysoft.Map6.Core.Entities.BaseEntity。
2.实体上必须具有 Mysoft.Map6.Core.EntityBase.EntityNameAttribute 特性并传入对应的实体元数据名称。
3.导航属性必须为虚属性,一对多的导航属性必须使用 IList<> 来声明。
4.数据库使用 int 存储,在实体中可以使用 bool、枚举类型,这一块做了兼容。
5.导航属性一定要和实体元数据关系保持一致,如果配置错误,平台会给出错误的提示。
4、为了更符合标准的 WebApi 调用模式,这次我们也引入了 AutoMapper,所以我们还要定义实体关联的 Dto,我们在代码中新增 ContractDto,ContractDetailDto,ContractDetailAttachmentDto类,分别对应以上三个实体,Dto 要继承于 BaseDto。
注册实体
在系统启动时,通过上篇文章提到的模块化加载,注册实体以及实体和 Dto 的映射关系。
仓储介绍
仓储定义:“在领域层和数据映射层的中介,使用类似集合的接口来存取领域对象”(Martin Fowler)。实际上,仓储被用于领域对象在数据库上的操作。
平台中的IRepository接口定义:
public
interface
IRepository<TEntity>{}
仓储接口说明
1、查询接口
查询接口包含单个查询和批量查询,单个查询默认会进行实体跟踪。批量GetAll()接口不会进行实体跟踪,如果需要进行实体跟踪,使用GetAllWithTracking()。不启用实体跟踪适用于不需要对实体进行修改和删除的操作,此时查询性能会更高。
2、新增接口
新增接口包含单个新增和批量新增,返回值为void,新增的时候会自动生成实体主键,如果需要获取主键,直接访问实体对应的主键属性即可。
3、更新接口目前暂未提供更新接口,默认通过实体跟踪,在应用服务结束时自动更新。
4、删除接口
删除接口支持根据Id或者实体删除单个实体,也支持根据条件批量删除实体。
5、其他接口
提供两个接口获取实体数量。
仓储的使用
仓储接口通过构造函数注入到领域服务中。