ABP官方文档翻译 3.1 实体

实体

  • 实体类
  • 聚合根类
    • 领域事件
  • 常规接口
    • 审计
    • 软删除
    • 激活/失活实体
  • 实体改变事件
  • IEntity接口

  实体是DDD(领域驱动设计)的核心概念之一。Eric Evans描述它为"An object that is not fundamentally defined by its attributes, but rather by a thread of continuity and identity."所以,实体有Id并存储在数据库。实体一般映射到关系库中的表。

实体类

  在ABP,实体继承自Entity类。如下示例:

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

  Persion类定义为实体。它有两个属性,实体类还定义了Id属性,它是实体的主键。所以,所有实体主键的名字都一样,为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或其他类型。

  实体类重写了相等运算符(==),可以方便的检查两个实体是否相等(Id相同)。实体还定义了IsTransient()方法检查是否有Id。

聚合根类

  “在DDD中,聚合是一种模式。一个DDD聚合是领域对象群集,这些领域对象可以作为一个单元对待。例如订单和它的行项目,这些是独立的对象,但是把订单(和它的行项目)作为一个聚合对待是有用的。”(Martin Fowler -参见详细描述)。

  虽然ABP不强制使用聚合,在应用中,我们或许想创建聚合和聚合根。ABP定义了AggregateRoot类,它扩展了实体为聚合创建聚合根实体。

领域事件

  聚合根定义了领域事件集合,通过聚合根类产生领域事件。这些事件在当前工作单元完成之前自动触发。实际上,任何实体可以通过实现IGeneratesDomainEvents接口来生成领域事件,但是,通常在(最佳实践)聚合根中生成领域事件。这就是为什么默认为聚合根而不是其他实体类。

常规接口

  在许多应用中,相似的实体属性(和数据库表字段)被使用,如CreationTime表示实体什么事件被创建。ABP提供了一些有用的接口使这些常见属性显示声明。这也提供了编写实体常用代码的一种方式,实现这些接口。

审计

  IHasCreationTime使实体拥有一个常用的"creation time"属性。当实现了这个接口的实体被插入到数据库时,ABP自动设置CreationTime为当前时间。

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

  ABP自动设置CreatorUserId为当前用户Id,当保存一个新实体的时候。也可以通过将实体继承CreationAuditedEntity类来实现ICreationAudited接口。它也有一个泛型版本,可以实现不同类型的Id属性。

  修改也有类似的接口:

复制代码
public interface IHasModificationTime
{DateTime? LastModificationTime { get; set; }
}public interface IModificationAudited : IHasModificationTime
{long? LastModifierUserId { get; set; }
}
复制代码

  当更新实体时,ABP自动设置这些属性。只需要在实体中定义他们。

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

public interface IAudited : ICreationAudited, IModificationAudited
{}

  有一个捷径,可以直接继承AuditedEntity类而不是直接实现IAudited接口。AuditedEntity类也有一个泛型版本,以适应不同类型的Id属性。

  注意:ABP从ABP会话中获取当前用户Id。

软删除

  软删除是常用的模式,用来标记实体删除而不是真的从数据库中删除。例如,可能不想从数据库中硬删除一个用户,因为它和其他表有许多关系。ISoftDelete接口用来实现这个目的:

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

  ABP实现了开箱即用的软删除模式。当软删除实体被删除时,ABP会检测到并阻止删除,设置IsDeleted为true,然后更新实体到数据库。ABP不会从数据库中获取(select)软删除的实体,自动过滤他们。

  如果使用软删除,也想记录实体什么时候被删除、谁删除,可以实现IDeletionAudited接口,如下所示:

复制代码
public interface IDeletionAudited : ISoftDelete
{long? DeleterUserId { get; set; }DateTime? DeletionTime { get; set; }
}
复制代码

  IDeletionAudited扩展了ISoftDelete接口。当实体被删除时,ABP自动记录这些属性。

  如果想让实体实现所有的审计接口(creation、modification和deletion),可以直接实现IFullAudited接口,因为它继承自所有接口:

public interface IFullAudited : IAudited, IDeletionAudited
{}

  有个捷径,可以使实体继承自FullAuditedEntity类,它实现了所有。

  • NOTE1:所有的审计接口和类都有一个泛型版本,用来定义User实体(如ICreationAudited<TUser>和FullAuditedEntity<TPrimaryKey,TUser>)的导航属性。
  • NOTE2:所有这些都有一个聚合根版本,如AuditedAggregateRoot。

激活/失活实体

  一些实体需要被记录为激活或失活。然后可以基于实体的激活/失活状态进行操作。可以实现IPassiveable接口,这个接口便是为这个目的设计的。它定义了IsActive属性。

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

  这和软删除(IsDeleted)是不同的。如果实体被软删除,它不能从数据库中获取(ABP默认会阻止获取),但是,对于激活/失活的实体,控制获取实体完全由自己决定。

实体改变事件

  当实体被插入、更新或删除时,ABP自动触发这些确定的事件。然后,我们可以注册这些事件,执行需要的任何逻辑。参见在事件总线文档的预定义事件部分了解更多信息。

IEntity接口

  实际上,Entity类实现了IEntity接口(Entity<TPrimaryKey>实现了IEntity<TPrimaryKey>)。如果不想从Entity类集成,可以直接实现这些接口。其他实体类也有相关的接口。但是,不建议使用这种方式,除非有好的理由不从Entity类继承。

 

返回主目录

转载于:https://www.cnblogs.com/luozhijun/p/6875699.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标检测之线段检测---lsd line segment detector

&#xff08;1&#xff09;线段检测应用背景 &#xff08;2&#xff09;线段检测原理简介 &#xff08;3&#xff09;线段检测实例 a line segment detector &#xff08;4&#xff09;hough 变换和 lsd 的区别 ---------------------author&#xff1a;pkf ------------------…

利用Mac创建一个 IPv6 WIFI 热点

标签&#xff1a; iOSIPv6Create NAT64 NetWork创建NAT64网络2016-05-20 10:58 14156人阅读 评论(11) 收藏 举报分类&#xff1a;开发技巧&#xff08;8&#xff09; 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 苹果商店6月1日起&#xff0c;强…

经典电影

那些经典的电影&#xff0c;第一波&#xff01;&#xff01; 《怦然心动》&#xff0c;欧美电影——布莱斯全家搬到小镇&#xff0c;邻家女孩朱丽前来帮忙。她对他一见钟情&#xff0c;心愿是获得他的吻。两人是同班同学&#xff0c;她一直想方设法接近他&#xff0c;但是他避之…

go-zero 微服务实战系列(一、开篇)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

大数据时代,怎么做全渠道的营销

大数据时代,怎么做全渠道的营销 营销在中国有很多变化&#xff0c;1978年之前主要是计划经济的时代&#xff0c;寻求政府的保护。1984年进入商品经济之后&#xff0c;中国企业通过大规模的扩大生产&#xff0c;扩大工厂得到生产效率。1992年进入市场经济之后&#xff0c;会涌现…

oracle slient静默安装并配置数据库及仅安装数据库不配置数据库shell

oracle slient静默安装并配置数据库及仅安装数据库不配置数据库shell <1&#xff0c;>仅安装数据库软件不配置数据库 ./x86oracle.sh /ruiy/ocr/DBSoftware/app/oracle /ruiy/ocr/DBSoftware/app/oraInventory /ruiy/ins_soft.rsp <2&#xff0c;>静默安装数据库软…

hdu 2048 神、上帝以及老天爷

题解&#xff1a; 本题主要思路是&#xff0c;算出i个人的总选择数a和以悲剧结尾的总选择数b&#xff0c;然后b/a&#xff0c;完成。属于递推题&#xff1a; 图中横杠代表人&#xff0c;竖杠代表签名。Ai代表i个人共有A[i]个选择&#xff0c;Bi起过度作用。因为最多有20人&…

探究Presto SQL引擎(3)-代码生成

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【学习笔记】计算几何

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

支持自动水平拆分的高性能分布式数据库TDSQL

随着互联网应用的广泛普及&#xff0c;海量数据的存储和访问成为系统设计的瓶颈问题。对于大型的互联网应用&#xff0c;每天几十亿的PV无疑对数据库造成了相当高的负载。给系统的稳定性和扩展性造成了极大的问题。通过数据的切分来提高系统整体性能&#xff0c;扩充系统整体容…

一些有趣的B+树优化实验

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

Tarjan的强联通分量

求强联通分量有很多种。 《C信息学奥赛一本通》 中讲过一个dfs求强联通分量的算法Kosdaraju&#xff0c;为了骗字数我就待会简单的说说。然而我们这篇文章的主体是Tarjan&#xff0c;所以我肯定说完之后再赞扬一下Tarjan大法好是不是 首先我们讲一下强联通分量 强联通分量指的…

XXE漏洞

简介 XXE (XML External Entity Injection) 漏洞发生在应用程序解析 XML 输入时&#xff0c;没有禁止外部实体的加载。 简单的理解&#xff0c;一个实体就是一个变量&#xff0c;可以在文档中的其他位置引用该变量。 实体主要分为四种&#xff1a; 内置实体 (Built-in entities…

Linq之Expression高级篇(常用表达式类型)

目录 写在前面 系列文章 变量表达式 常量表达式 条件表达式 赋值表达式 二元运算符表达式 一元运算符表达式 循环表达式 块表达式 总结 写在前面 首先回顾一下上篇文章的内容&#xff0c;上篇文章介绍了表达式树的解析和编译。如果忘记了&#xff0c;可以通过下面系列文章提供的…

NetCore框架WTM的分表分库实现

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

WordPress WP Photo Album Plus插件‘wppa-tag’跨站脚本漏洞

漏洞名称&#xff1a;WordPress WP Photo Album Plus插件‘wppa-tag’跨站脚本漏洞CNNVD编号&#xff1a;CNNVD-201301-458发布时间&#xff1a;2013-01-24更新时间&#xff1a;2013-01-24危害等级&#xff1a; 漏洞类型&#xff1a;跨站脚本威胁类型&#xff1a;远程CVE编号&…

SpringCloudAlibaba分布式流量控制组件Sentinel实战与源码分析(上)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【单元测试框架unittest】

转载于:https://www.cnblogs.com/ppppying/p/6899750.html

C++ 炼气期之基本结构语法中的底层逻辑

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

优惠券的工厂与策略模式实现方案

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…