我正在建模的学生和考勤功能使用DDD聚合。我最后的结果是学生班有一张考勤记录的清单。我使用EF核心加载学生和所有与学生相关的出席。
因此,每天都会有一份针对学生的出勤记录。出勤记录可在一天内多次更新。最后,我在学生类中创建了一个名为CreateOrUpdateAttendance(日期日期,AttendanceDetails考勤)的公共方法,该方法将在内部检查给定日期是否有考勤记录,如果没有创建新的考勤实例,则使用提供的出勤详细信息添加/更新与学生相关的考勤列表更新此考勤记录。因此,每次为学生更新/创建出勤率时,都会从数据库中查询学生实体以及所有考勤记录。根据输入的Id查询学生,以检查所提供的Id是否有效。
问题是,随着时间的推移,会有许多与学生相关的出勤记录,这意味着不必要地提取与学生相关的所有考勤记录,这将导致查询性能不佳。
学生在这里是合适的根吗?不幸的是,EF核心还不支持过滤子对象。
我的问题是如何处理在聚合中需要更新子实体的用例,更具体地说,是聚合内实体列表中的单个实体?
在这种情况下,我应该把出席人数视为不同的总和吗?这样我就可以独立于学生记录查询考勤记录了吗?
最后,我打了两个电话到数据库,一个是检查学生(没有加载出勤率),另一个是获取出勤记录。
我漏掉了什么吗?我该重新考虑一下我的设计吗?任何指导都会很有帮助。
发布于 2019-10-09 14:03:01
是学生这里的合适根吗?
聚合是一个一致性边界。它的存在是为了确保其中所包含的实体处于与您的业务规则相关的一致(即有效)状态。您还没有描述任何应该确保的业务规则或验证,所以我不知道Student是正确的聚合。继续读..。
不幸的是,
EF核心还不支持过滤子对象。
EF不支持过滤子集合,但可能还有其他方法来实现这一点。下面是一些pseuodcode:
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吗?这仅仅是一个读取用例吗?
还要考虑一个学生的总和是否足够。当你只想改变一个电话号码时,你应该加载所有的出勤记录吗?正如我们有有界的上下文一样,您可能会考虑有有界的集合,例如在有界上下文中的聚合的垂直分区,将听起来像是一个单一的大概念分成几个较小的概念。
你可以拥有:
,我漏掉了什么东西?我该重新考虑一下我的设计吗?
那得看情况。通常,我建议在域级别多思考,在DB级别少思考。多考虑写作而不是阅读。
EF迫使我们在某种程度上以关系的方式思考,甚至在我们对域建模时也是如此,但我们应该与此作斗争,尽可能将EF简化为一个简单的持久性机制,而不是让它驱动我们的领域设计决策。
https://stackoverflow.com/questions/58287470
复制相似问题