views:

171

answers:

2

I have two entities User and Course. A user can take several courses which makes the relationship one to many. But a single course can be taken by many students so it makes it many to many relationship.

Now, I need to register a course for a user. My user entity has:

 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});
        }

The classes are generated through Linq to SQL. Linq to sql is not capable of performing many to many relationships so I have to handle it myself.

Now, the question is that how will I send the information to the database. Should UserRepository.Save(user) be responsible for saving the courses.

This kind of means that User is aggregate root of Course entity but in real it is not since I can access Course many different ways and I am not dependent on the User object to provide me Course.

Even if I have a CourseRegistrationService (which I have) I have to call a repository to persist the changes. Which repository is responsible for persisting the changes about user and course relationship. Maybe a UserCourseRepository!!

Also, just by putting a List under User object makes User an aggregate root or is that incorrect. If so then how would you design application using OR MAPPERS which generates List and one to many relationships automatically.

A: 

I ran into a similar solution, but used a completely different approach. I added code to my LINQ to SQL classes so that they properly supported Many-to-Many relationships. Check this blog post for the final details:

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

As for which repository should handle adding a Student to a Class Course, your Service name should give you a hint (CourseRegistrationService). The Course repository should be adding students to a class.

Justin Niessner
There is no entity called Class. There is User and Course. User can register for a course. Also, is User has List<Course> then I can just save the user and it will persist the courses also.
azamsharp
Editted to remove Class. As for your second point, the same thing could be said about List<Student> for Course. All you have to do is add the Student to the Course and save the Course.
Justin Niessner
kind of like this: I am calling Registration as UserCourses. I will change to CourseRegistrations since it is more meaninful. Check out http://pastie.org/795679
azamsharp
+3  A: 

In DDD terms you should be thinking of aggregates and aggregate roots. Does a User "own" the course? Probably not.

Instead, thinking of it like this might give you a better design:

User has many Registrations. Registration is associated with 1 course.

Now you don't have a many to many. You have a first class object that the User entity "owns".

Registration would be a value object (that has UserID, CourseID, and perhaps DateAdded).

Regarding using methods to add to both sides of a collection, this is something that I do as well with NHibernate.

Ben Scheirman
Thanks Ben! This was informative!
azamsharp