Reputation: 347
Currently I learn CQRS and DDD without Event Sourcing (not yet). I need to return from my repository to a query handler a model different from a domain model. Should I create a read model in a domain project? I need to use this read model in a repository (an infrastructure project), a repository interface (a domain project) and a query handler (an application project)?
A further description:
In my database I have a table Posts related to a table Comments. There is a foreign key: PostId in the table Comments. And this is a domain model in my project, as you can see there is no PostId in Comment:
public class Post : Entity, IAggregateRoot
{
public Guid PostId { get; private set; }
public string Title { get; private set; }
public string Content { get; private set; }
public List<Comment> Comments { get; private set; }
}
public class Comment : Entity
{
public Guid CommentId { get; private set; }
public string Author { get; private set; }
public string Content { get; private set; }
}
I would like to return from my repository a comment which contains not only CommentId
, Author
, Content
but also PostId
and PostTitle
. This is my repository:
public class CommentsRepository : ICommentsRepository
{
private readonly ApplicationDbContext _applicationDbContext;
public CommentsRepository(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public async Task<Comment> GetByIdAsync(Guid id)
{
var comment = await _applicationDbContext.Comments
.SingleOrDefaultAsync(x => x.CommentId == id);
return comment;
}
}
Should I create a model CommentReadModel
(with properties: CommentId
, Author
, Content
, PostId
and PostTitle
) and write SQL in the repository to fill in that model? If yes, where should I place that model because it will be needed in 3 projects:
ICommentsRepository
)CommentsRepository
)Upvotes: 5
Views: 4624
Reputation: 115
You should place your read model in Domain Layer of course. And you also should throw any complexity away while implementing read side of your app. Repositories are good when working with write models (aggregates), because they can encapsulate some infrastructure logic (e.g domain events dispatching, logging, etc.). You don't need any of these features on the read side. Just use Entity Framework's (or Dapper's) engine in your query handlers and fetch data directly or implement some lightweight query facade over them if you prefer.
You can also read this Microsoft article about query-side in CQRS applications.
Upvotes: 6