我正在按照CQRS和Mediatr模式进行项目。
我有一个这样设置的实体
MSC000001: Failed to start service jboss.web.deployment.default-host
Start Exception in service jboss.web.development.default-host./
当我编写两个查询GetAllOrdersCreatedByUser和GetAllOrdersAcceptedByUser时,所有代码实际上是相同的。
唯一的例外是在Created查询中,我的位置在CreatedByUserId上,而我的Accepted查询中的位置在AcceptedByUserId上
GetAllOrdersAcceptedByUser:-
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; }
}
GetAllOrdersCreatedByUser:-
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;
}
这是正确的实现,还是客观上更好的是让1个查询可以同时执行两个查询,这取决于从控制器调用它的方式?
编辑:添加了更好的标签
答案 0 :(得分:1)
查询可以保持分开(因此它们遵循SOLID),并且您可以通过其他某种方式避免代码重复。也许尝试提取查询的重复部分以获取订单,而无需先在where
方法中使用virtual
对其进行过滤,然后再在相应的查询中对其进行过滤。
答案 1 :(得分:1)
您可以将规范模式应用于查询,即以谓词为参数的一个查询。
但是DDD提倡使用一种无所不在的语言,如果您的用户不使用谓词,而是使用具体的方法名称,我将向用户提供2个查询,然后,如果您不想重复代码,则两个查询会使用谓词调用通用查询。
答案 2 :(得分:0)
首先,合并类GetAllOrdersCreatedByUserQuery
和GetAllOrdersAcceptedByUserQuery
请参阅以下类以供参考:
public class GetAllOrdersByUserQuery : : IRequest<OrdeListViewModel>
{
// if OrderAcceptedByUser is true else OrderCreatedByUser = false
public bool AcceptedOrCreatedBit { get; set; }
public string UserId { get; set; }
}
并同时查看OrderCreatedByUserListViewModel and OrderCreatedByUserListViewModel
的视图模型
请参阅以下视图模型以供参考:
public class OrdeListViewModel
{
public List<Order> Orders { get; set; }
}
最后,您的MediatR处理方法应如下所示:
public async Task<OrdeListViewModel> Handle(GetAllOrdersByUserQuery request, CancellationToken cancellationToken)
{
OrdeListViewModel model = new OrdeListViewModel();
if (request.AcceptedOrCreatedBit) // true for OrderAcceptedByUser
{
model.Orders = await _context.Order
.Where(x => x.AcceptedByUserId == request.UserId)
.Select(OrderDto.Projection)
.OrderBy(o => o.Registration)
.ToListAsync(cancellationToken)
}
else // false for OrderCreatedByUser
{
model.Orders = await _context.Order
.Where(x => x.CreatedByUserId == request.UserId)
.Select(OrderDto.Projection)
.OrderBy(o => o.Registration)
.ToListAsync(cancellationToken)
}
return model;
}