返回总目录


本篇目录

实体是DDD(领域驱动设计)的核心概念之一。Eirc Evans是这样描述的实体的:“它根本上不是通过属性定义的,而是通过一系列连续性和标识定义的”。因此,实体都有Id属性并且都存储到数据库中。一个实体一般会映射到数据库的一张表。

实体类###

在ABP中,实体派生自Entity类,看下面的例子:

public class Person : Entity
{
public virtual string Name { get; set; } public virtual DateTime CreationTime { get; set; } public Person()
{
CreationTime = DateTime.Now;
}
}

上面定义了一个Person实体类,而且在Entity类中定义了一个Id属性,它是该Entity类的 主键。因此,所有实体的主键名都是相同的,都是Id

Id(主键)的类型是可以改变的,默认是int(int32)的。如果你想将Id定义为其他类型,可以像下面那样显示声明:

public class Person : Entity<long>
{
public virtual string Name { get; set; } public virtual DateTime CreationTime { get; set; } public Person()
{
CreationTime = DateTime.Now;
}
}

而且,你也可以把它设置为string,Guid或其他类型的。

Entity类重写了等号运算符(==),可以轻松地检查两个实体是否相同了(实体的Id相同则认为它们相同)。它也定义了IsTransient方法来检测它是否有Id。

惯例接口###

在许多应用中,使用了相似的实体属性(和数据表中的字段),如CreationTime表明该实体是何时创建的。ABP提供了很多有用的接口来使得这些通用的属性变得明确并富有表现力。此外,这也为实现了这些接口的实体类提供了一种编写通用代码的方式。

审计

IHasCreationTime使得使用一个通用的属性来描述一个实体的“创建时间”信息成为可能。当实现了该接口的实体类插入到数据库中时,ABP会自动地将当前的时间设置给CreationTime。

public interface IHasCreationTime
{
DateTime CreationTime { get; set; }
}

Person类可以通过实现IHasCreationTime接口来重写,如下所示:

public class Person : Entity<long>, IHasCreationTime
{
public virtual string Name { get; set; } public virtual DateTime CreationTime { get; set; } public Person()
{
CreationTime = DateTime.Now;
}
}

ICreationAudited通过增加了CreatorUserId扩展了IHasCreationTime:

public interface ICreationAudited : IHasCreationTime
{
long? CreatorUserId { get; set; }
}

当保存一个新的实体时,ABP会自动地将当前的用户Id设置为CreatorUserId。

你也可以通过从CreationAuditedEntity类派生实体,从而轻易地实现ICreationAudited。

对于修改也有相似的接口:

public interface IModificationAudited
{
DateTime? LastModificationTime { get; set; } long? LastModifierUserId { get; set; }
}

当更新一个实体的时候,ABP也会自动地设置这些属性。你只需要为你的实体实现这些接口即可。

如果你想实现所有的审计属性,那么你可以直接实现IAudited接口:

public interface IAudited : ICreationAudited, IModificationAudited
{ }

作为一个快捷方式,你可以从AuditedEntity类派生,而不需要直接实现IAudited。AuditedEntity类对于不同类型的Id属性也有泛型的版本。

软删除

软删除是将一个实体标记为已删除的通常使用的模式,而不是直接从数据库中删除。比如,你可能不想从数据库中硬删除一个User,因为它可能关联其他的表。ISoftDelete接口用于下面的目的:

public interface ISoftDelete
{
bool IsDeleted { get; set; }
}

ABP实现了开箱即用的软删除模式。当一个软删除实体被删除后,ABP检测到之后,会阻止删除,将IsDeleted设置为true并更新数据库中的实体。而且,它会自动地过滤数据库中软删除的实体,不会检索(select)它们。

如果使用了软删除,那么你可能想存储一些信息,比如何时删除以及谁删除了一个实体等等。你可以实现下面演示的IDeletionAudited接口:

public interface IDeletionAudited : ISoftDelete
{
long? DeleterUserId { get; set; } DateTime? DeletionTime { get; set; }
}

IDeletionAudited扩展了ISoftDelete,当删除一个实体时,ABP会自动设置这些属性。

如果你想为一个实体实现所有的审计接口(创建,修改和删除),那么可以直接实现IFullAudited,因为它继承了所有的这些接口:

public interface IFullAudited : IAudited, IDeletionAudited
{ }

同样的,作为一个快捷方式,你可以从FullAuditedEntity类派生你的实体类从而实现所有的审计接口。

注意:所有的审计接口和类都有一个定义导航属性到User实体的泛型版本(比如ICreationAudited和FullAuditedEntity<TPrimaryKey,TUser>)。

激活/未激活

一些实体需要标记为激活的或未激活的。这样,你就可以根据实体的激活或者未激活状态来采取行动。你可以实现IPassivable接口来达到目的。该接口定义了IsActive属性。

如果实体在第一次创建时是激活的,那么你可以在构造函数中将IsActive设置为true。

这与软删除(IsDeleted)是不同的。如果一个实体是软删除的,那么它就不会从数据库中检索到了(ABP默认会阻止),但是,对于激活或者未激活的实体,控制获取实体完全取决于你。

IEntity接口###

实际上,Entity类实现了IEntity接口(且Entity实现了IEntity)。如果不想从Entity类中派生,那么可以直接实现这些接口。但是,除非你有一个好的原因不从Entity类派生,否则,不建议这么做。

ABP理论学习之实体类的更多相关文章

  1. Abp项目中的领域模型实体类访问仓储的方法

    首先声明,不推荐使用这种方法.实体访问仓储是不被推荐的! 1.简单粗暴的方法 Abp.Dependency.IocManager.Instance.Resolve>(); 2.绕个弯子的方法 首 ...

  2. abp 修改abp.zero的实体映射类,使生成的表和字段为大写状态

    在我们项目中,由于涉及到报表配置管理,可以通过一段sql快捷的配置出一个报表页面.部分sql会与abp框架的一些系统表做关联查询,而abp的映射类没有单独设置表和字段的名称,默认用类名和属性名,区分大 ...

  3. 关于EF实体类的一点思考

    在EF中修改一条记录时,一般是先查出该条记录,然后再通过TryUpdateModel或其他方式更新对应的属性.但我很讨厌这种要更新一条记录时,还要先去把记录查询出来的做法.我喜欢像sql语句那样的直接 ...

  4. ABP(现代ASP.NET样板开发框架)系列之10、ABP领域层——实体

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之10.ABP领域层——实体 ABP是“ASP.NET Boilerplate Project (ASP.NET样板 ...

  5. ABP理论学习之仓储

    返回总目录 本篇目录 IRepository接口 查询 插入 更新 删除 其他 关于异步方法 仓储实现 管理数据库连接 仓储的生命周期 仓储最佳实践 Martin Fowler对仓储的定义 位于领域层 ...

  6. ABP理论学习之领域服务

    返回总目录 本篇目录 介绍 IDomainService接口和DomainService类 样例 创建一个接口 服务实现 调用应用服务 一些讨论 何不只使用应用服务 如何强制使用领域服务 介绍 领域服 ...

  7. ABP理论学习之数据过滤器

    返回总目录 本篇目录 介绍 预定义过滤器 关闭过滤器 开启过滤器 设置过滤器参数 定义自定义过滤器 其他ORM 介绍 软删除模式通常用于不会真正从数据库删除一个实体而是仅仅将它标记为"已删除 ...

  8. ABP理论学习之OData集成(新增)

    返回总目录 本篇目录 介绍 安装 创建控制器 例子 样例项目 介绍 OData在其官网的定义是: 允许以一种 简单且标准的方式创建和使用可查询的.可互操作的RESTful APIs. 在ABP中也可以 ...

  9. ABP理论学习之Javascript API(理论完结篇)

    返回总目录 本篇目录 Ajax Notification Message UI block和busy 事件总线 Logging 其他工具功能 说在前面的话 不知不觉,我们送走了2015,同时迎来了20 ...

随机推荐

  1. zTree和SweetAlert插件初探

    1.zTree插件简介 zTree是一个依靠 jQuery实现的多功能“树插件”.优异的性能.灵活的配置.多种功能的组合是zTree最大优点.专门适合项目开发,尤其是树状菜单.树状数据的Web显示.权 ...

  2. 怎么使用Delphi获取当前的时间,精确到毫秒

    先介绍一个可能比较常用的方法,获取当前时间 var datetime: string; begin datetime:= FormatDateTime('yyyy-mm-dd hh:mm:ss', N ...

  3. jsf组件对应表

    组件 标签 说明 UIForm form 表示 HTML表单元素 UIInput InputText 单行文本输入控件   inputTextarea 多行文本输入控件   InputSecret 密 ...

  4. CPT单臂路由

    路由器配置:Router>enableRouter#configure terminal        进入全局配置模式Router(config)#int fa0/1        进入端口R ...

  5. parted LVM划分4T磁盘,在线扩展1.5T

      磁盘分区: parted /dev/emcpowera (parted) print Model: Unknown (unknown) Disk /dev/emcpowera: 4398GB Se ...

  6. mysql 字符串 日期互转

    一.字符串转日期 下面将讲述如何在MySQL中把一个字符串转换成日期: 背景:rq字段信息为:20100901 1.无需转换的: SELECT * FROM tairlist_day WHERE rq ...

  7. #英文#品读中国城市个性——最好的和最坏的&当东方遇到西方

    冒险家的乐园 a playground of risk 实现发财梦 realize one's dreams of wealth 道德沦丧,堕落 moral deprivation 租界 foreig ...

  8. 解决EditText和ScrollView滑动冲突问题

    该类需要调用 OnTouchListener接口 黄色部分是需要更改部分,改为自己的edittext@Override public boolean onTouch(View view, Motion ...

  9. VOF 方法捕捉界面--粘性剪切流动算例

    流体体积法(Volume ofFluid)是一种典型的界面追踪方法,这种方法选取流体体积分数为界面函数S.它通过定义一个体积分数$ C $(指定的流体体积分数占网格体积的百分比)来描述界面.因此只有所 ...

  10. python/matplotlib库的安装