I am working on a project following CQRS and Mediatr pattern.
I have an entity set up like this
public class Order
{
public Guid OrderId { get; set; }
public Guid CreatedByUserId { get; set; }
public Guid? AcceptedByUserId { get; set; }
public string Registration { get; set; }
public string Description { get; set; }
public User CreatedByUser { get; set; }
public User AcceptedByUser { get; set; }
}
When i'm writing my 2 queries GetAllOrdersCreatedByUser & GetAllOrdersAcceptedByUser all the code is virtually the same.
The only exception to that is on the Created query my where is on CreatedByUserId and my Accepted query where is on AcceptedByUserId
GetAllOrdersAcceptedByUser :-
public async Task<OrderAcceptedByUserListViewModel> Handle(GetAllOrdersAcceptedByUserQuery request, CancellationToken cancellationToken)
{
var model = new OrderAcceptedByUserListViewModel
{
Orders = await _context.Order
.Where(x => x.AcceptedByUserId == request.UserId)
.Select(OrderDto.Projection)
.OrderBy(o => o.Registration)
.ToListAsync(cancellationToken)
};
return model;
}
GetAllOrdersCreatedByUser:-
public async Task<OrderCreatedByUserListViewModel> Handle(GetAllOrdersCreatedByUserQuery request, CancellationToken cancellationToken)
{
var model = new OrderCreatedByUserListViewModel
{
Orders = await _context.Order
.Where(x => x.CreatedByUserId == request.UserId)
.Select(OrderDto.Projection)
.OrderBy(o => o.Registration)
.ToListAsync(cancellationToken)
};
return model;
}
Is this the correct implementation or is it objectively better to have 1 query that can do both depending on how its called from the controller?
Edit: Added better tags
The queries could stay separate (so they follow SOLID) and you could avoid code duplication by some other means. Maybe try extracting the recurring part of the query to get the orders without filtering them using where
in a virtual
method first and filter then them in the respective queries.