Search code examples
c#domain-driven-designdbcontextcqrsmediatr

DDD, CQRS and Mediatr query filtering


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


Solution

  • 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.