在实体中包含集合是不是违反了实体的本应?

Posted

技术标签:

【中文标题】在实体中包含集合是不是违反了实体的本应?【英文标题】:Does including Collections in Entities violate what an entity is supposed to be?在实体中包含集合是否违反了实体的本应? 【发布时间】:2022-01-19 17:43:34 【问题描述】:

我正在使用 Dapper for .NET Core 构建 Web API,并尝试遵守清洁架构原则。该 API 由外部 Angular 前端使用。

我有使用 Dapper 从数据库中检索数据的存储库,然后这些数据通过服务被映射到 DTO 以显示给用户。

我的理解是,实体应该是数据库对象的精确表示,没有额外的属性,如果我需要一些额外的属性来显示用户(或如果我也希望隐藏用户的某些属性)。

假设我有一个 DTO:

public class StudentDTO

  public Guid Id  get; set; 
  public string Name  get; set; 
  public List<Assignment> Assignments  get; set;

及其对应的实体:

public class Student

  public Guid Id  get; set; 
  public string Name  get; set; 

使用这个模型,如果我想让一个学生完成所有作业,我需要调用两个存储库,并在服务中执行类似的操作:

public StudentDTO GetById(Guid id) 

  var student = this.studentRepository.GetById(id);
  var assignments = this.assignmentRepository.GetByStudentId(id);
  return SomeMapperClass.Map(student, assignments);

但这似乎效率低下且没有必要。我的问题是,当我在存储库中获取学生实体时,我是否应该使用 JOIN 来检索作业?或者这会违反实体的本应是什么?

抱歉,我确实意识到这是一个相当简单的问题,但我真的很想知道哪种方法是最好的方法,或者它们是否都有自己的用例

【问题讨论】:

github.com/DapperLib/Dapper/blob/main/Readme.md#multi-mapping 【参考方案1】:

我觉得这样会更有效率,因为地图使用反射,慢了几十倍

public StudentDTO GetById(Guid id) 

  var student = this.studentRepository.GetById(id);
 student.Assignments = this.assignmentRepository.GetByStudentId(id);
 return student;

但常见的方式是

return _context.Students.Include(i=>i.Assignments).FirstOrDefault(i=> i.Id==id);

这就是为什么在大多数情况下通用存储库不是一个好主意,因为很难猜测您将需要什么数据集。

【讨论】:

以上是关于在实体中包含集合是不是违反了实体的本应?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate - 是不是需要在父实体中包含 Set 和 OneToMany 注释?

如何在实体框架中包含排序的导航属性[重复]

是否可以在约束中包含 Core Data 实体类型?

DbContext 模型中包含啥?

使用 DTO 和实体是不是违反了 DRY 原则?

在持久化实体之前检查是不是违反约束