1

Domain Driven Design states that you should have a domain model, which reflects the ubiquitious language used by the domain experts. When using ORMs and many to many relationships I am use to doing this:

public class Student
{
    public Student() 
    {
        this.Courses = new HashSet<Course>();
    }

    public int StudentId { get; set; }
    [Required]
    public string StudentName { get; set; }

    public virtual ICollection<Course> Courses { get; set; }
}

public class Course
{
    public Course()
    {
        this.Students = new HashSet<Student>();
    }

    public int CourseId { get; set; }
    public string CourseName { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

However, with EF Core you must create a join class as described here: https://github.com/aspnet/EntityFrameworkCore/issues/1368. In the case of the above; I would have to create a class called: StudentCourse.

What is the most appropriate way to map an ORM to a Domain Model assuming there are no technical constraints like with EF Core were you must currently have a join class? My thinking is:

1) If the join table has state and behaviour then use a join class.

2) If the join table has a name that is recognised by domain experts then use a join class e.g. a Person could be eligible for loans - here Eligibility is the join class and is a term recognised by the domain. In the case of the above; StudentCourse is not recognised by the domain.

3) Else don't use a join class (like in the example above).

  • I thought EF allowed you to omit the join class if the table only contained two foreign keys? – Greg Burghardt Nov 29 '18 at 0:19
  • 4
    ORM to a Domain Modelnone. DDD is totally agnostic to how the data is stored. You are trying to converge both domain model and persistence model in a single model. DDD is not data-centric, is domain centric. In other words, we first do model the business (domain) and later we decide how to persist it – Laiv Nov 29 '18 at 14:10
  • 1
    if you are using CQRS, then the command model maps to the database or does it? this is your assumption. The truth is that if you model a system following DDD, the persistence is a mere implementation detail. It could be a (R)elational (D)ata (M)odel or it could be a (D)ocument (D)ata (M)odel. Or it could be binaries stored somehow into somewhere. DDD shift from data-centric models to domain-centric models. When you converge domain and persistence in the same model, the ORM is likely to impose its constraints. The common one is to break encapsulation, what it's totally contrary to DDD – Laiv Nov 29 '18 at 14:35
  • 1
    @w0051977 Laiv is completely right. The domain model is not supposed to be a "data" model, at least not in object-orientation. Most of the projects I see do that anyway too. That just means that the idea didn't penetrate our old habits yet. I must say, that I'm not a fan of a "completely isolated" (as in: "persistence agnostic") domain model. I think objects should contain business-relevant behavior, and most of those contain some form of persistence implicitly. – Robert Bräutigam Nov 30 '18 at 8:45
  • 1
    @Vincent Savard, I would just like to see an example to see how change tracking is approached without the ORM mapped to the domain model. – w0051977 Nov 30 '18 at 17:43
0

The overarching paradigm that DDD seeks to provide is one focused on the behavior of your system. Everything else is an implementation detail. As such, one does not model the domain according to any specific persistence mechanism, rather, models the persistence mechanism according to the domain. Including some sort of "join" object in your domain for the sake of easing persistence to an RDBMS creates an unnecessary coupling and pollutes/obfuscates your model with persistence concerns.

You specific problem is caused by mixing the data model that an ORM requires with the domain model that your application requires. There is no DDD solution to employ here other than to decouple the former from the latter above.

ORMs are a great tool (cohesive mechanism) for generating a necessarily anemic data model (methods cannot be serialized within reason) and mapping to/from a necessarily anemic data store. Put another way, an ORM only provides a more OO experience for developers and offers a (leaky) abstraction over a data store. That's all. That is the goal of every ORM (what does it stand for again?).

That said, there are two types of applications:

The overwhelming majority of systems are trivial. That is, they simply collect and persist data then turn around and display it back to the user. Trivial applications boil down to CRUD with a few rules sprinkled here and there regarding (mostly) the format/range of data being entered. In such systems it's not usually necessary to isolate a domain model (or isolate only small portions of it) because there are so few rules.

The second type of application is the one that truly benefits from an isolated domain. It is an application with lots of business rules. Often this kind of application defines many types of object that aren't persisted at all, or includes lots of Aggregates. This makes isolating a domain paramount. An ORM's data model can only truly provide the consistency boundaries an Aggregate requires through discipline (not structure) because all of the Entities are made available (and mutable).

Whether or not you have "seen" this kind of application is beside the point, and does not invalidate the fundamental principals of clean architecture. Every decision is a trade off. A good software architect understands that and moves accordingly. If the costs of creating an isolated domain model are not worth the benefits, move forward accordingly. But understand the trade off. That's what systems design is all about: finding the perfect balance between business concerns and technical concerns. It's about pragmatism. Leave idealism to academics and jr. developers, and utilitarianism to CEOs. We are here to provide balance. That is our value.

  • Thanks. Do you know any DDD projects on Github that contain an isolated domain model? I know of many DDD projects on GitHub, however they all map the domain model straight to the database – w0051977 Nov 30 '18 at 17:40
  • @w0051977 If you have an actual question about how one implements an isolated domain model or a related concept, I am more than happy to expound on that. I have no interest in engaging with such a sardonic question. It is simply beneath me to take your implication seriously. – king-side-slide Nov 30 '18 at 20:11
  • Not sure how my comment is sardonic (disrespectful?), but thanks for answering anyway - always grateful for answers. – w0051977 Nov 30 '18 at 20:28

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.