簡體   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