ABP框架系列之一:(Entity-实体)
Entities are one of the core concepts of DDD (Domain Driven Design). Eric Evans describe it as "An object that is not fundamentally defined by its attributes, but rather by a thread of continuity and identity". So, entities have Id's and stored in a database. An entity is generally mapped to a table for relational databases.
实体是DDD(领域驱动设计)的核心概念之一。Eric Evans把它描述为“一个没有被它的属性基本定义的对象,而是一个连续性和同一性的线程”。因此,实体拥有id并存储在数据库中。实体通常映射到关系数据库的表。
Entity Class(实体类)
In ASP.NET Boilerplate, 实体是从实体类派生的. See the sample below:
public class Person : Entity
{
public virtual string Name { get; set; } public virtual DateTime CreationTime { get; set; } public Person()
{
CreationTime = DateTime.Now;
}
}
Person class is defined as an entity. It has two properties. Also, Entity class defines an Id property. It's primary key of the Entity. So, name of primary keys of all Entities are same, it's Id.
Type of Id (primary key) can be changed. It's int (Int32) by default. If you want to define another type as Id, you should explicitly declare it as shown below:
人员类定义为一个实体。它有两个属性。此外,实体类定义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;
}
}
Also, you can set it as string, Guid or something else.
Entity class overrides equality operator (==) to easily check if two entities are equal (their Id is equal). It also defines the IsTransient() method to check if it has an Id or not.
另外,可以将其设置为字符串、GUID或其他内容。
实体类重写相等运算符(=)以轻松检查两个实体是否相等(它们的ID是相等的)。它还定义了istransient()方法检查它是否有一个ID或不。
AggregateRoot Class(聚合根类)
"Aggregate is a pattern in Domain-Driven Design. A DDD aggregate is a cluster of domain objects that can be treated as a single unit. An example may be an order and its line-items, these will be separate objects, but it's useful to treat the order (together with its line items) as a single aggregate." (Martin Fowler - see full description)
“聚合是领域驱动设计中的一种模式。DDD聚合是一组域对象,可以作为单个单元处理。一个例子可能是一个订单和它的行项目,它们将是单独的对象,但是将订单(连同它的行项目)作为单个集合处理是有用的。”(Martin Fowler -参见完整描述)
While ABP does not enforce you to use aggregates, you may want to create aggregates and aggregate roots in your application. ABP defines AggregateRoot class that extends Entity to create aggregate root entities for an aggregate.
虽然ABP不强制您使用聚合,但您可能希望在应用程序中创建聚合和聚合根。 ABP定义聚合根类,为了类扩展的实体创建一个聚集根实体。
(1)Domain Events(领域事件)
AggregateRoot defines DomainEvents collection to generate domain events by the aggregate root class. These events are automatically triggered just before the current unit of work is completed. Actually, any entity can generate domain events by implementing IGeneratesDomainEvents interface, but it's common (best practice) to generate domain events in aggregate roots. That's why it's default for AggregateRoot but not for Entity class.
聚合根定义领域事件集合,通过聚合根类自动生成领域事件。这些事件是在当前工作单元完成之前自动触发的。事实上,任何实体可以通过继承 Igeneratesdomainevents接口自动生成领域的事件,但它是常见的(最佳实践),用聚合根自动生成领域事件。这就是为什么它的默认聚合根而不是实体类。
Conventional Interfaces(接口约定)
In many application, similar entity properties (and database table fields) are used like CreationTime indicates that when this entity is created. ASP.NET Boilerplate provides some useful interfaces to make this common properties explicit and expressive. Also, this provides a way of coding common code for Entities which implement these interfaces.
在许多应用中,类似的实体属性(和数据库表的字段)是用于 CreationTime表明这个实体的创建。ASP.NET的模板提供了一些有用的接口,使这个共同的属性的明确和有表达力。此外,这为实现这些接口的实体提供了一种编码公共代码的方法。
(1)Auditing(审计)
IHasCreationTime makes it possible to use a common property for 'creation time' information of an entity. ASP.NET Boilerplate automatically sets CreationTime to current time when an Entity is inserted into database which implements this interface.
ihascreationtime使得它可以使用一个共同的属性的一个实体的创建时间信息。ASP.NET样板自动设置的创建时间为当前时间当实体插入到数据库中,只要实现这个接口
public interface IHasCreationTime
{
DateTime CreationTime { get; set; }
}
Person class can be re-written as shown below by implementing IHasCreationTime interface:
人员类能被重写如下通过实现 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 extens IHasCreationTime by adding CreatorUserId:
ICreationAudited扩展IHasCreationTime,增加 CreatorUserId属性
public interface ICreationAudited : IHasCreationTime
{
long? CreatorUserId { get; set; }
}
ASP.NET Boilerplate automatically sets CreatorUserId to current user's id when saving a new entity. You can also implement ICreationAudited easily by deriving your entity from CreationAuditedEntity class. It has also a generic version for different type of Id properties.
ASP.NET 样板自动设置CreatorUserId作为当前用户的ID,当存储一个新的实体时。你也可以很容易的实现icreationaudited,通过CreationAuditedEntity获得你的实体类。它还有一个通用版本,用于不同类型的id属性。
There is also similar interfaces for modifications:
public interface IHasModificationTime
{
DateTime? LastModificationTime { get; set; }
} public interface IModificationAudited : IHasModificationTime
{
long? LastModifierUserId { get; set; }
}
ASP.NET Boilerplate also automatically sets these properties when updating an entity. You just define them for your entity.
If you want to implement all of audit properties, you can direcly implement IAudited interface:
ASP.NET样板也自动设置这些属性,当一个实体时更新。你只需为你的实体定义它们。
如果你想实现所有审计的属性,你可以直接实现iaudited接口:
public interface IAudited : ICreationAudited, IModificationAudited
{ }
As a shortcut, you can derive from AuditedEntity class instead of direcly implementing IAudited. AuditedEntity class has also a generic version for different type of Id properties.
Note: ASP.NET Boilerplate gets current user's Id from ABP Session.
作为一种快捷方式,你可以从auditedentity类而不是直接实现iaudited。auditedentity类也有不同类型的ID属性的通用版本。
注:ASP.NET样板从会话获取当前用户的ID ABP。
(2)Soft Delete(软删除)
Soft delete is a commonly used pattern to mark an Entity as deleted instead of actually deleting it from database. For instace, you may not want to hard delete a User from database since it has many releations to other tables.ISoftDelete interface is used for this purpose:
软删除是一种常用模式,用于将实体标记为已删除,而不是实际从数据库中删除它。如,你可能不想从数据库中删除用户因为它有许多关系到其他tables.isoftdelete接口用于此目的的:
public interface ISoftDelete
{
bool IsDeleted { get; set; }
}
ASP.NET Boilerplate implements soft delete pattern out-of-the-box. When a soft-delete entity is being deleted, ASP.NET Boilerplate detects this, prevents deleting, sets IsDeleted as true and updates entity in the database. Also, it does not retrive (select) soft deleted entities from database, automatically filters them.
ASP.NET样板实现软删除模式开箱。当软删除实体被删除,ASP.NET样板检测,防止删除、设置isDeleted作为真正的更新数据库实体。而且,它没有获得(选择)软删除实体数据库,自动过滤。
If you use soft delete, you may also want to store information when an entity is deleted and who deleted it. You can implement IDeletionAudited interface that is shown below:
如果你使用软删除,则可能希望在删除实体和谁删除它时记录信息。你可以实现ideletionaudited接口,如下图所示:
public interface IDeletionAudited : ISoftDelete
{
long? DeleterUserId { get; set; } DateTime? DeletionTime { get; set; }
}
IDeletionAudited extends ISoftDelete as you noticed. ASP.NET Boilerplate automatically sets these properties when an entity is deleted.
If you want to implement all audit interfaces (creation, modification and deletion) for an entity, you can directly implement IFullAudited since it inherits all:
当你注意到 ideletionaudited扩展isoftdelete 。ASP.NET样板自动设置这些属性,当一个实体被删除。
如果你想实现所有审计接口(创建,修改和删除)一个实体,可以直接实现ifullaudited因为它继承了所有:
public interface IFullAudited : IAudited, IDeletionAudited
{ }
As a shortcut, you can derive your entity from FullAuditedEntity class that implements all.
- NOTE 1: All audit interfaces and classes have a generic version for defining navigation property to your User entity (like ICreationAudited<TUser> and FullAuditedEntity<TPrimaryKey, TUser>).
NOTE 2: Also, all of them has an AggregateRoot version, like AuditedAggregateRoot.
作为一种快捷方式,你可以从fullauditedentity得到你的实体类,实现了所有。
注1:所有审计接口和类都定义导航属性用户实体的通用版本(如 ICreationAudited<TUser> and FullAuditedEntity<TPrimaryKey, TUser>)。
注2:同时,他们都有一个aggregateroot版,如AuditedAggregateRoot。
(3)Active/Passive Entities(激活/闲置实体)
Some entities need to be marked as Active or Passive. Then you may take action upon active/passive state of the entity. You can implement IPassivable interface that is created for this reason. It defines IsActive property.
If your entity will be active on first creation, you can set IsActive to true in the constructor.
This is different than soft delete (IsDeleted). If an entity is soft deleted, it can not be retrieved from database (ABP prevents it as default). But, for active/passive entities, it's completely up to you to control getting entities.
一些实体需要标记为激活或闲置。然后你可以对实体的激活或闲置状态采取行动。你可以实现ipassivable接口就是这个原因了。它定义了IsActive属性。
如果你的实体将第一次创作是激活的,你可以设置 IsActive = true在构造函数。
这是不同于软删除(isDeleted)。如果一个实体被软删除,它不能从数据库中检索(ABP防止它作为默认)。但是,对于激活/闲置实体,完全由您来控制获取实体。
Entity Change Events(实体改变事件)
ASP.NET Boilerplate automatically triggers certain events when an entity is inserted, updated or deleted. Thus, you can register to these events and perform any logic you need. See Predefined Events section in event bus documentation for more information.
ASP.NET样板自动触发某些事件时,一个实体的插入、更新或删除。因此,您可以注册这些事件并执行您需要的任何逻辑。有关详细信息,请参阅事件总线文档中的预定义事件部分。
IEntity Interfaces(IEntity 接口)
Actually, Entity class implements IEntity interface (and Entity<TPrimaryKey> implements IEntity<TPrimaryKey>). If you do not want to derive from Entity class, you can implement these interfaces directly. There are also corresponding interfaces for other entity classes. But this is not the suggested way, unless you have a good reason to do not derive from Entity classes.
实际上,实体类实现的接口(and Entity<TPrimaryKey> implements IEntity<TPrimaryKey>)。如果不希望从实体类派生,则可以直接实现这些接口。其他实体类也有相应的接口。但这不是建议的方法,除非您有很好的理由不从实体类派生出来。
IExtendableObject Interface(IExtendableObject接口)
ASP.NET Boilerplate provides a simple interface, IExtendableObject, to easily associate arbitrary name-value data to an entity. Consider this simple entity:
ASP.NET的模板提供了一个简单的接口,iextendableobject,很容易联想到一个实体任意name-value数据。考虑这个简单的实体:
public class Person : Entity, IExtendableObject
{
public string Name { get; set; } public string ExtensionData { get; set; } public Person(string name)
{
Name = name;
}
}
IExtendableObject just defines ExtensionData string property which is used to store JSON formatted name value objects. Example:
IExtendableObject 定义ExtensionData string 属性用来存储json格式的name-value objects,如:
var person = new Person("John");
person.SetData("RandomValue", RandomHelper.GetRandom(1, 1000));
person.SetData("CustomData", new MyCustomObject { Value1 = 42, Value2 = "forty-two" });
We can use any type of object as value to SetData method. When we use such the code above, ExtensionData will be like that:
我们可以使用任何类型的对象作为值SetData方法。当我们使用上面的代码,extensiondata如下:
{"CustomData":{"Value1":42,"Value2":"forty-two"},"RandomValue":178}
Then we can use GetData to get any value:
用GetData取得任意的值
var randomValue = person.GetData<int>("RandomValue");
var customData = person.GetData<MyCustomObject>("CustomData");
While this technique can be very useful in some cases (when you need to provide ability to dynamically add extra data to an entity), you normally should use regular properties. Such a dynamic usage is not type safe and explicit.
虽然这种技术在某些情况下非常有用(当您需要提供向实体动态添加额外数据的能力时),但您通常应该使用常规属性。这种动态用法不是类型安全的和显式的。
ABP框架系列之一:(Entity-实体)的更多相关文章
- 老周的ABP框架系列教程 -》 一、框架理论初步学习
老周的ABP框架系列教程 -- 一.框架理论初步学习 1. ABP框架的来源与作用简介 1.1 简介 1.1.1 ABP框架全称为"ASP.NET Boilerplate ...
- 2019 年起如何开始学习 ABP 框架系列文章-开篇有益
2019 年起如何开始学习 ABP 框架系列文章-开篇有益 [[TOC]] 本系列文章推荐阅读地址为:52ABP 开发文档 https://www.52abp.com/Wiki/52abp/lates ...
- ABP框架系列之三十四:(Multi-Tenancy-多租户)
What Is Multi Tenancy? "Software Multitenancy refers to a software architecture in which a sing ...
- ABP框架系列之四:(Repositories-仓库)
"Mediates between the domain and data mapping layers using a collection-like interface for acce ...
- ABP框架系列之十一:(AspNet-Core-ASPNET核心)
Introduction This document describes ASP.NET Core integration for ASP.NET Boilerplate framework. ASP ...
- ABP框架系列之五十四:(XSRF-CSRF-Protection-跨站请求伪造保护)
Introduction "Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a maliciou ...
- ABP框架系列之三:(Entity Framework Integration-实体框架集成)
ASP.NET Boilerplate can work with any O/RM framework. It has built-in integration with EntityFramewo ...
- ABP框架系列之二:(Entity Framework Core-实体核心框架)
Introduction(介绍) Abp.EntityFrameworkCore nuget package is used to integrate to Entity Framework (EF) ...
- ABP框架系列之八:(Introduction-介绍)
Introduction We are creating different applications based on different needs. But implementing commo ...
- ABP框架系列之三十八:(NHibernate-Integration-NHibernate-集成)
ASP.NET Boilerplate can work with any O/RM framework. It has built-in integration with NHibernate. T ...
随机推荐
- oracle体系结构理解
体系结构相关内容每次看遍书,过段时间就忘了..无奈用自己理解的方式记录之. 1.commit与写盘与否没有关系,也就是说修改数据(insert update delete)后并提交数据,这条被修改的数 ...
- java中的静态变量、静态方法与静态代码块详解与初始化顺序
我们知道类的生命周期分为装载.连接.初始化.使用和卸载的五个过程.其中静态代码在类的初始化阶段被初始化. 而非静态代码则在类的使用阶段(也就是实例化一个类的时候)才会被初始化. 静态变量 可以将静 ...
- Oracle 学习笔记(六)
Oracle 数据库常用的闪回sql 语句及其它操作语句: --Oracle 数据库dml sql -- 查看当前用户所拥有的表 select * from tab; --表空间,auto: 自动管理 ...
- mysql修改用户密码的方法及命令
方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...
- CMake,win10,64位,简单配置测试
https://cmake.org/download/ 下载完成后,解压即可. 创建文件夹,文件路径自己选择: 这里,就近选择在桌面--创建HelloWorld档,在该文档下,分别创建CMakeLis ...
- Redux的梳理
学习Redux之前,我了解了它需要去解决什么问题: 用户使用方式复杂 不同身份不同使用方式 多个用户可以协作 与服务器大量交互,或者使用websocket 视图数据从多个来源获取 共享组件状态 组件之 ...
- YAML基本语法
正如YAML所表示的YAML Ain’t Markup Language,YAML /ˈjæməl/ 是一种简洁的非标记语言.YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易 ...
- vue.js建立一个简单的表格
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- [Ting's笔记Day8]活用套件carrierwave gem:(3)Deploy图片上传功能到Heroku网站
前情提要: 身为Ruby新手村民,创造稳定且持续的学习步调很重要,我用的方法就是一周在IT邦写三篇笔记,希望藉由把笔记和遇到的bug记录下来的过程,能帮助到未来想用Ruby on Rails架站的新手 ...
- faster rcnn源码阅读笔记1
自己保存的源码阅读笔记哈 faster rcnn 的主要识别过程(粗略) (开始填坑了): 一张3通道,1600*1600图像输入中,经过特征提取网络,得到100*100*512的feature ma ...