简体   繁体   English

如何保持命令处理程序清洁查询逻辑? (CQRS 和 MediatR)

[英]How to keep the command handler clean of querying logic? (CQRS and MediatR)

The problem that I am dealing with is how to keep my controllers free of querying logic that really should be an Infrastructure rather that Application concern.我正在处理的问题是如何让我的控制器不受查询逻辑的影响,这些逻辑实际上应该是基础设施而不是应用程序关注的问题。

Down below is an example of Command and CommandHandler.下面是 Command 和 CommandHandler 的示例。 I am using MediatR by the way.顺便说一下,我正在使用 MediatR。

As you can see, the Command contains some filters (which I think is ok, that does not violate CQRS) but the Command Handler has too much logic in it.如您所见,Command 包含一些过滤器(我认为这没问题,不违反 CQRS)但 Command Handler 中有太多逻辑。 I am not sure that is something that the handler has to deal with.我不确定这是处理程序必须处理的事情。

GetMatchesCommand获取匹配命令

public class GetMatchesCommand : IRequest<IEnumerable<MatchDto>>
{
    public Tuple<DateTime, DateTime> TimeInterval { get; set; }
    public Guid? Location { get; set; }
    public Guid? Team { get; set; }
    public Guid? Player { get; set; }
}

GetMatchesCommandHandler获取匹配命令处理程序

public class GetMatchesCommandHandler : IRequestHandler<GetMatchesCommand, IEnumerable<MatchDto>>
{       
    public async Task<IEnumerable<MatchDto>> Handle(GetMatchesCommand request, CancellationToken cancellationToken)
    {
        Expression<Func<Match, bool>> filterExpression = default;
            
        // Build the filter expression

        // Filter by interval
        if (request.TimeInterval != null)
            filterExpression.ConcatAnd(
                m => m.StartTime >= request.TimeInterval.Item1
                && (m.StartTime + m.Duration) <= request.TimeInterval.Item2);

        // Filter by team
        if (request.Team != null)
            filterExpression.ConcatAnd(
                m => m.Team1Id == request.Team
                || m.Team2Id == request.Team);

        // Filter by player
        if (request.Player != null)
            filterExpression.ConcatAnd(
                m => m.Team1.Players.Any(p => p.Id == request.Player)
                || m.Team2.Players.Any(p => p.Id == request.Player));

        var query = _dbContext.Matches
            .Include(m => m.Team1).ThenInclude(t => t.Players)
            .Include(m => m.Team2).ThenInclude(t => t.Players);

        // if there are any filters, apply them
        if(filterExpression != null)
        {
            query.Where(filterExpression);
        }

        var matches = query.ToListAsync();
        return _mapper.Map<List<MatchDto>>(matches);
    }
}

I know that the repository pattern might be suitable for this case, but still, what would be the right way of doing it?我知道存储库模式可能适合这种情况,但是,正确的做法是什么? Having a _matchesRepo.Get(interval, team, player, location) and moving this logic there does not seem to be a very smart approach to be honest...有一个_matchesRepo.Get(interval, team, player, location)并将这个逻辑移到那里,老实说似乎不是一个非常聪明的方法......

Can someone give me an advice on this?有人可以给我建议吗? Thank you in advance!先感谢您!

GetMatches should probably be understood as a query , rather than a command , based on the example you have provided here.根据您在此处提供的示例, GetMatches可能应该被理解为查询,而不是命令

The key hint being that your implementation is effectively read only - you aren't making changes to your model and saving them in the repository.关键提示是您的实现实际上是只读的 - 您没有对模型进行更改并将其保存在存储库中。

Filtering in a query handler is a normal thing to do.在查询处理程序中进行过滤是一件很正常的事情。

You could probably simplify the design here by encapsulating the construction of the filter expression into another function (separation of concerns / information hiding).您可以通过将过滤器表达式的构造封装到另一个函数(关注点分离/信息隐藏)来简化这里的设计。

I am doing the similar project about football match, can you share your code and expericence in design database and UI.我正在做一个关于足球比赛的类似项目,你能分享你在设计数据库和UI方面的代码和经验吗?

Have you finished it.你做完了吗。 I also want to write the same function and using AJAX to get result (list of Match) when user typing on textbox but someone told me about performance when you send request to server on eachtime button downevent (user typing one more charactor)我还想编写相同的函数并在用户在文本框上输入时使用 AJAX 来获取结果(匹配列表),但是有人告诉我在每次按钮按下事件时向服务器发送请求时的性能(用户再输入一个字符)

Thanks.谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM