繁体   English   中英

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

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

我正在处理的问题是如何让我的控制器不受查询逻辑的影响,这些逻辑实际上应该是基础设施而不是应用程序关注的问题。

下面是 Command 和 CommandHandler 的示例。 顺便说一下,我正在使用 MediatR。

如您所见,Command 包含一些过滤器(我认为这没问题,不违反 CQRS)但 Command Handler 中有太多逻辑。 我不确定这是处理程序必须处理的事情。

获取匹配命令

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; }
}

获取匹配命令处理程序

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);
    }
}

我知道存储库模式可能适合这种情况,但是,正确的做法是什么? 有一个_matchesRepo.Get(interval, team, player, location)并将这个逻辑移到那里,老实说似乎不是一个非常聪明的方法......

有人可以给我建议吗? 先感谢您!

根据您在此处提供的示例, GetMatches可能应该被理解为查询,而不是命令

关键提示是您的实现实际上是只读的 - 您没有对模型进行更改并将其保存在存储库中。

在查询处理程序中进行过滤是一件很正常的事情。

您可以通过将过滤器表达式的构造封装到另一个函数(关注点分离/信息隐藏)来简化这里的设计。

我正在做一个关于足球比赛的类似项目,你能分享你在设计数据库和UI方面的代码和经验吗?

你做完了吗。 我还想编写相同的函数并在用户在文本框上输入时使用 AJAX 来获取结果(匹配列表),但是有人告诉我在每次按钮按下事件时向服务器发送请求时的性能(用户再输入一个字符)

谢谢。

暂无
暂无

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

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