areller
areller

Reputation: 5238

Relational Reference in Domain Objects - Include Id or Not?

I want to know what is the best way for designing my domain objects for my project.

The domain objects should be ignorant of the ORM/Framework and even the database technology (MySQL, MSSQL, and even Mongo)

And the next question comes in mind, lets say that i have two objects, Post and Comment.

This is the code for the Post object:

class Post {
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public IList<Comment> Comments { get; set; }
}

Now, my question for the Comment object is should it include a Post Id or just a Post object?

class Comment {
    public int Id { get; set; }
    public string Content { get; set; }
    public Post Post { get; set; }

    public int PostId { get; set; } // Should i include it?
}

Is it a good practice to include the Id of the relational object or just its domain object?

Another concern is for no sql database like mongodb. If i store my data in mongodb, what Post object will the Comment object reference? In mongodb there is no relationship between post and comments, any post includes list of comments, but the comments themselves are ignorant of the post they are part of. So what is the best way to make those domain classes compatible both with Sql based database and NoSql databases?

Thank you

Upvotes: 1

Views: 975

Answers (2)

MobileMon
MobileMon

Reputation: 8651

Absolutely you should include it. What if you want to get a list of comments but don't want to get the Post object with each comment, yet still need the PostID?

Upvotes: 0

theDmi
theDmi

Reputation: 18034

Object-oriented design

You designed your Post and Comment classes in a way that they both reference each other. While I'd try to avoid this tight coupling unless absolutely necessary, it surely makes Comment.PostId obsolete, you can just call Post.Id from within a Comment.

Also, your domain objects should probably try to protect their invariants. What you have now is just property bags (even with public setters), and not domain objects, so currently they don't offer any meaningful advantage over the objects you'd use for persistence.

So if you want to create a domain model, ask yourself questions like these:

  • What can an actor do with a post in the system I'm building?
  • What data on a comment can an actor retrieve?

Then model your domain objects in a way that supports your business cases. For example, if users of your application are prohibited to change the title of a post, you should remove the setter from Post.Title.

This answer may give you more information on the distinction between domain objects and simple property bags (aka POCOs), even though that answer is in the context of domain-driven design.

Document DB Persistence

To store these objects in a document-oriented DB, you have basically two choices:

  • Store them as separate documents and reference one from the other
  • Store comments as part of their post on the post document

Both are valid approaches, you have to decide for your application. Note however that document boundaries are also consistency boundaries, so if you need atomic operations on a post and its comments, your only option is to put them on the same document.

Upvotes: 1

Related Questions