聚合内的聚合列表

问题描述 投票:-1回答:1

我正在使用DDD聚合对学生和出勤功能进行建模。我最终得到的是学生班级,其中包含一份出勤记录列表。我正在使用EF Core加载学生以及与该学生相关的所有出勤。

因此,每天都会有针对学生的出勤记录。一天中的出勤记录可以多次更新。我最终在Student类上创建了一个公共方法,称为CreateOrUpdateAttendance(Date date,AttendanceDetails勤工),如果没有创建新的勤工实例,它将内部检查给定日期是否有任何勤工记录,请使用提供的勤工更新该勤工记录详细信息添加/更新与学生相关的出勤列表。因此,每次为学生更新/创建一个出勤记录时,都会从数据库中查询学生实体以及所有出勤记录。根据从输入中收到的ID来查询学生,以检查提供的ID是否有效。

问题是随着时间的流逝,与学生相关的出勤记录很多,这意味着不必要地拉扯了与学生相关的所有出勤记录,这将导致查询性能下降。

学生在这里是正确的根吗?不幸的是,EF核心尚不支持过滤子对象。

我的问题是如何处理需要在聚合内更新子实体的用例,更具体地说,聚合内实体列表中的单个实体?

在这种情况下,我应该将出勤表视为不同的汇总表吗?这样我就可以独立于学生记录查询出勤记录了吗?

我最后打了两次电话给数据库,一次是检查学生(不加载出勤率,另一次是获取出勤记录。

我在这里想念什么吗?我应该重新考虑设计吗?任何指导都会很有帮助。

sql-server design-patterns domain-driven-design microservices ef-core-2.0
1个回答
0
投票

学生在这里是正确的根吗?

聚合是一致性边界。存在确保与您的业务规则有关的实体处于一致(即有效)状态的存在。您尚未描述应确保的任何业务规则或验证,因此我不知道Student是正确的汇总。继续阅读...

不幸的是,EF核心还不支持过滤子对象。

EF Core不支持过滤子集合,但是可能有其他方法可以实现此目的。这是一些伪代码:

var query = 
    from s in ctx.Students
    where s.Id == 1 // Student filter here
    select new 
    {
        Student = s,
        Student = 
            from sa in s.StudentAttendances
            where sa. // Apply filter here
            select sa
    };

// Perform the query against the DB and then return the Student object
// EF will wire up the relationships for you and because you went to the
// DB first before pulling the student, the data is local and you will
// have the full tree
var student = query.ToList().Select(x => x.Student).FirstOrDefault();

在这种情况下,我应该将出勤表视为不同的汇总表吗?这样我就可以独立于学生记录查询出勤记录了吗?

取决于您的业务规则。学生和出勤的寿命是多少?学生可以参加任何数量的出勤吗?多考虑您的写用例,而不是您的读用例。您是否需要加载StudentAttendances?这仅仅是一个阅读用例吗?

[还要考虑一个学生合计是否足够。当您只想更改电话号码时,是否应该加载所有的出勤记录?就像我们有绑定的上下文一样,您可能会考虑使用绑定的聚合,例如绑定上下文中聚合的垂直分区将听起来像一个单一的大型概念拆分为几个较小的概念。

您可以拥有:

  • 具有筛选出的出勤列表的学生集合(如上所述)
  • 一个学生出勤汇总(如您所述)
  • 与学生汇总表分开并用于不同用例的StudentWithAttendance汇总表>
  • 我在这里想念什么吗?我应该重新考虑设计吗?

取决于。

© www.soinside.com 2019 - 2024. All rights reserved.