领域驱动设计问题:服务和仓储

3
我是一个有用的助手,可以翻译文本。
我有两个实体User和Course。用户可以选多门课程,这使得关系为一对多。但是单个课程可以被多名学生选修,因此它成为多对多的关系。
现在,我需要为用户注册课程。我的用户实体具有:
 public void AddCourse(Course course)
        {
            if (CoursesAlreadyAdded(course))
            {
                AddBrokenRule(new BrokenRule() { PropertyName = course.ClassCode, Message = String.Format("Course with classCode = {0} already added", course.ClassCode) });
                return;
            }

            UserCourses.Add(new UserCourse() { UserId = this.UserId, CourseId = course.CourseId, Course= course, User = this});
        }

这段文字描述了使用Linq to SQL生成类,但是Linq to SQL无法处理多对多关系,因此需要手动处理。问题在于如何将信息发送到数据库。UserRepository.Save(user)是否负责保存课程。这意味着User是Course实体的聚合根,但实际上不是,因为可以通过许多不同的方式访问Course,不依赖于User对象提供Course。即使有一个CourseRegistrationService(我有),我也必须调用存储库来保存更改。哪个存储库负责保存有关用户和课程关系的更改。也许是UserCourseRepository!只是在User对象下放置一个List是否会使User成为聚合根,或者这是不正确的。如果是这样,那么您将如何使用自动生成List和一对多关系的OR MAPPERS设计应用程序。

听起来数据模型已经设置好了,但是我认为通过将连接表实体化为注册模型,避免多对多关系可能会让你省去一些麻烦。 - Thom Smith
@Thom,不确定你的意思!你能详细说明一下吗? - azamsharp
基本上就是接受的答案所说的。 - Thom Smith
2个回答

4
在DDD术语中,您应该考虑聚合和聚合根。用户是否“拥有”课程?很可能不是这样的。
相反,像这样思考可能会给你更好的设计:
用户有多个注册。 注册与1门课程相关联。
现在您没有一个多对多。 您有一个用户实体“拥有”的一流对象。
注册将成为值对象(具有UserID,CourseID和可能的DateAdded)。
关于使用方法添加到集合的两侧,我也会在NHibernate中这样做。

0

我遇到了类似的问题,但是采用了完全不同的方法。 我在我的LINQ到SQL类中添加了代码,以便它们正确支持多对多的关系。请查看此博客文章以获得最终细节:

Mitsu's blog: How to implement a many-to-many relationship using LINQ to SQL

至于哪个仓库应该处理将学生添加到班级 课程,您的服务名称应该给您一个提示 (CourseRegistrationService)。课程仓库应该将学生添加到一个课程中。


没有叫做Class的实体。有User和Course两个实体。用户可以注册课程。而且,如果User有一个List<Course>,我只需要保存用户,课程也会被持久化保存。 - azamsharp
关于你提到的第二点,List<Student> 和 Course 的情况其实也是一样的。你只需要将 Student 添加到 Course 中并保存 Course 即可。 - Justin Niessner
我正在将“Registration”称为“UserCourses”。我会改为“CourseRegistrations”,因为它更有意义。请查看http://pastie.org/795679。 - azamsharp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接