diff --git a/docs/zh-Hans/Best-Practices/Entities.md b/docs/zh-Hans/Best-Practices/Entities.md index 03843c5278..637ecaef6d 100644 --- a/docs/zh-Hans/Best-Practices/Entities.md +++ b/docs/zh-Hans/Best-Practices/Entities.md @@ -1,98 +1,98 @@ -## Entity Best Practices & Conventions +## 实体最佳实践 & 约定 -### Entities +### 实体 -Every aggregate root is also an entity. So, these rules are valid for aggregate roots too unless aggregate root rules override them. +每个聚合根也是一个实体, 所以这些规则对聚合根也是有效的, 除非聚合根的某些规则覆盖了它们. -- **Do** define entities in the **domain layer**. +- **推荐** 在 **领域层** 中定义实体. -#### Primary Constructor +#### 主构造函数 -* **Do** define a **primary constructor** that ensures the validity of the entity on creation. Primary constructors are used to create a new instance of the entity by the application code. +* **推荐** 定义一个 **主构造函数** 确保实体在创建时的有效性, 在代码中通过主构造函数创建实体的新实例. -- **Do** define primary constructor as `public`, `internal` or `protected internal` based on the requirements. If it's not public, the entity is expected to be created by a domain service. -- **Do** always initialize sub collections in the primary constructor. -- **Do not** generate `Guid` keys inside the constructor. Get it as a parameter, so the calling code will use `IGuidGenerator` to generate a new `Guid` value. +- **推荐** 根据需求把主构造函数定义为 `public`,`internal` 或 `protected internal` . 如果它不是public的, 那么应该由领域服务来创建实体. +- **推荐** 总是在主构造函数中初始化子集合. +- **不推荐** 在主构造函数中生成 `Guid` 键, 应该将其做为参数获取, 在调用时推荐使用 `IGuidGenerator` 生成新的 `Guid` 值做为参数. -#### Parameterless Constructor +#### 无参构造函数 -- **Do** always define a `protected` parameterless constructor to be compatible with ORMs. +- **推荐** 总是定义 `protected` 无参构造函数与ORM兼容. -#### References +#### 引用 -- **Do** always **reference** to other aggregate roots **by Id**. Never add navigation properties to other aggregate roots. +- **推荐** 总是通过 **id** **引用** 其他聚合根, 不要将导航属性添加到其他聚合根中. -#### Other Class Members +#### 类的其他成员 -- **Do** always define properties and methods as `virtual` (except `private` methods, obviously). Because some ORMs and dynamic proxy tools require it. -- **Do** keep the entity as always **valid** and **consistent** within its own boundary. - - **Do** define properties with `private`, `protected`, `internal ` or `protected internal` setter where it is needed to protect the entity consistency and validity. - - **Do** define `public `, `internal` or `protected internal` (virtual) **methods** to change the properties (with non-public setters) if necessary. +- **推荐** 总是将属性与方法定义为 `virtual` (除了`私有`方法 ). 因为有些ORM和动态代理工具需要. +- **推荐** 保持实体在自身边界内始终 **有效** 和 **一致**. + - **推荐** 使用 `private`,`protected`,`internal`或`protected internal` setter定义属性, 保护实体的一致性和有效性. + - **推荐** 定义 `public`, `internal` 或 `protected internal` (virtual)**方法**在必要时更改属性值(使用非public setters时). -### Aggregate Roots +### 聚合根 -#### Primary Keys +#### 主键 -* **Do** always use a **Id** property for the aggregate root key. -* **Do not** use **composite keys** for aggregate roots. -* **Do** use **Guid** as the **primary key** of all aggregate roots. +* **推荐** 总是使用 **Id** 属性做为聚合根主键. +* **不推荐** 在聚合根中使用 **复合主键**. +* **推荐** 所有的聚合根都使用 **Guid** 类型 **主键**. -#### Base Class +#### 基类 -* **Do** inherit from the `AggregateRoot` or one of the audited classes (`CreationAuditedAggregateRoot`, `AuditedAggregateRoot` or `FullAuditedAggregateRoot`) based on requirements. +* **推荐** 根据需求继承 `AggregateRoot` 或以下一个审计类 (`CreationAuditedAggregateRoot`, `AuditedAggregateRoot` 或 `FullAuditedAggregateRoot`). -#### Aggregate Boundary +#### 聚合边界 -* **Do** keep aggregates **as small as possible**. Most of the aggregates will only have primitive properties and will not have sub collections. Consider these as design decisions: - * **Performance** & **memory** cost of loading & saving aggregates (keep in mind that an aggregate is normally loaded & saved as a single unit). Larger aggregates will consume more CPU & memory. - * **Consistency** & **validity** boundary. +* **推荐** 聚合**尽可能小**. 大多数聚合只有原始属性, 不会有子集合. 把这些视为设计决策: + * 加载和保存聚合的 **性能** 与 **内存** 成本 (请记住,聚合通常是做为一个单独的单元被加载和保存的). 较大的聚合会消耗更多的CPU和内存. + * **一致性** & **有效性** 边界. -### Example +### 示例 -#### Aggregate Root +#### 聚合根 ````C# -public class Issue : FullAuditedAggregateRoot //Using Guid as the key/identifier +public class Issue : FullAuditedAggregateRoot //使用Guid作为键/标识符 { - public virtual string Title { get; private set; } //Changed using the SetTitle() method - public virtual string Text { get; set; } //Can be directly changed. null values are allowed - public virtual Guid? MilestoneId { get; set; } //Reference to another aggregate root + public virtual string Title { get; private set; } //使用 SetTitle() 方法set + public virtual string Text { get; set; } //可以直接set,null值也是允许的 + public virtual Guid? MilestoneId { get; set; } //引用其他聚合根 public virtual bool IsClosed { get; private set; } - public virtual IssueCloseReason? CloseReason { get; private set; } //Just an enum type - public virtual Collection Labels { get; protected set; } //Sub collection + public virtual IssueCloseReason? CloseReason { get; private set; } //一个枚举类型 + public virtual Collection Labels { get; protected set; } //子集合 protected Issue() { - /* This conctructor is for ORMs to be used while getting the entity from database. - * - No need to initialize the Labels collection - since it will be overrided from the database. + /* 此构造函数是提供给ORM用来从数据库中获取实体. + * - 无需初始化Lanels集合 + 因为它会被来自数据库的值覆盖. - It's protected since proxying and deserialization tools - may not work with private constructors. + 可能不适用于私有构造函数. */ } - //Primary constructor + //主构造函数 public Issue( - Guid id, //Get Guid value from the calling code - [NotNull] string title, //Indicate that the title can not be null. + Guid id, //从调用代码中获取Guid值 + [NotNull] string title, //表示标题不能为空. string text = null, - Guid? milestoneId = null) //Optional argument + Guid? milestoneId = null) //可选参数 { Id = id; - Title = Check.NotNullOrWhiteSpace(title, nameof(title)); //Validate + Title = Check.NotNullOrWhiteSpace(title, nameof(title)); //验证 Text = text; MilestoneId = milestoneId; - - Labels = new Collection(); //Always initialize the collection + + Labels = new Collection(); //总是初始化子集合 } public virtual void SetTitle([NotNull] string title) { - Title = Check.NotNullOrWhiteSpace(title, nameof(title)); //Validate + Title = Check.NotNullOrWhiteSpace(title, nameof(title)); //验证 } - /* AddLabel & RemoveLabel methods manages the Labels collection - * in a safe way (prevents adding the same label twice) */ + /* AddLabel和RemoveLabel方法管理Labels集合 + * 安全的方式(防止两次添加相同的标签) */ public virtual void AddLabel(Guid labelId) { @@ -109,8 +109,8 @@ public class Issue : FullAuditedAggregateRoot //Using Guid as the key/iden Labels.RemoveAll(l => l.LabelId == labelId); } - /* Close & ReOpen methods protect the consistency - * of the IsClosed and the CloseReason properties. */ + /* Close和ReOpen方法可保护一致性 + * IsClosed 与 CloseReason 属性. */ public virtual void Close(IssueCloseReason reason) { @@ -126,7 +126,7 @@ public class Issue : FullAuditedAggregateRoot //Using Guid as the key/iden } ```` -#### The Entity +#### 实体 ````C# public class IssueLabel : Entity @@ -136,7 +136,7 @@ public class IssueLabel : Entity protected IssueLabel() { - + } public IssueLabel(Guid issueId, Guid labelId) @@ -147,7 +147,7 @@ public class IssueLabel : Entity } ```` -### References +### 参考文献 * Effective Aggregate Design by Vaughn Vernon http://dddcommunity.org/library/vernon_2011 \ No newline at end of file diff --git a/docs/zh-Hans/Entity-Framework-Core.md b/docs/zh-Hans/Entity-Framework-Core.md index 4a06bb2610..77d26e9b2f 100644 --- a/docs/zh-Hans/Entity-Framework-Core.md +++ b/docs/zh-Hans/Entity-Framework-Core.md @@ -1,6 +1,6 @@ ## Entity Framework Core 集成 -本文档介绍了如何将EF Core作为ORM提供程序集成到基于ABP的应用程序以及如何对其进行配置. +本文介绍了如何将EF Core作为ORM提供程序集成到基于ABP的应用程序以及如何对其进行配置. ### 安装