2010-01-26 50 views
3

我有两个实体用户和课程。用户可以参加几门课程,使得这种关系成为一对多关系。但是,许多学生可以选择一门课程,因此它可以为许多人提供很多关系。服务和存储库的域驱动设计问题

现在,我需要为用户注册一门课程。我的用户实体有:

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(用户)负责保存课程。

这种方式意味着用户是课程实体的聚合根,但实际上它并不是我可以访问课程的许多不同方式,而且我不依赖于用户对象来提供课程。

即使我有CourseRegistrationService(我有),我必须调用一个存储库来坚持更改。哪个存储库负责持久化关于用户和课程关系的更改。也许UserCourseRepository!

此外,仅通过在用户对象下放置一个列表使用户成为聚合根或者是不正确的。如果是这样,那么你将如何使用OR MAPPERS来设计应用程序,它会自动生成List和一对多关系。

+0

听起来好像数据模型已经设置好了,但在我看来,通过将连接表作为注册模型来避免多对多关系,您可以节省一些头痛。 – 2010-01-26 20:56:45

+0

@Thom,不知道你的意思!你能详细说明一下吗? – azamsharp 2010-01-26 21:03:38

+0

基本上接受的答案是什么。 – 2010-01-28 16:25:51

回答

4

在DDD术语中,您应该考虑聚合和聚合根。用户是否拥有课程?可能不会。

相反,它的思想是这样可能会给你一个更好的设计:

用户有很多注册。 注册与1课程相关。

现在你没有多对多。你有一个用户实体“拥有”的第一类对象。

注册将是一个值对象(具有UserID,CourseID和可能的DateAdded)。

关于使用方法添加到集合的两侧,这是我做的和NHibernate一样。

+0

谢谢本!这是信息! – azamsharp 2010-01-26 21:05:11

0

我遇到了类似的解决方案,但使用了完全不同的方法。我将代码添加到我的LINQ to SQL类中,以便它们正确支持多对多关系。检查这个博客帖子的最后细节:

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

至于哪个版本库应该处理增加了学生的 类课程,你的服务名称应该给你一个提示(CourseRegistrationService)。课程资源库应该将学生添加到课程中。

+0

没有实体叫做Class。有用户和课程。用户可以注册一门课程。另外,是用户有名单然后我可以保存用户,它也会坚持课程。 – azamsharp 2010-01-26 21:02:39

+0

编辑删除类。至于你的第二点,关于课程列表可以说同样的事情。您只需将学生添加到课程并保存课程。 – 2010-01-26 21:05:20

+0

有点像这样:我打电话注册为UserCourses。由于更有意思,我将改为CourseRegistrations。退房http://pastie.org/795679 – azamsharp 2010-01-26 21:13:38