You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MediatR模式中传递对象数组作为请求参数?

解决MediatR批量请求的CS0311错误

错误原因

你遇到的CS0311错误,本质是**AddFieldCommand[]数组没有实现MediatR的IRequest<TResponse>接口**,不符合IRequestHandler<TRequest, TResponse>对泛型参数TRequest的要求——它必须是实现了IRequest的具体类型,而数组类型不满足这个约束。

解决方案

MediatR的设计模式是单个请求对应单个处理器,要处理批量添加场景,需要创建一个包含请求集合的"聚合请求类",而非直接使用数组作为参数。具体步骤如下:

1. 创建聚合请求类

新建一个包含AddFieldCommand集合的请求类,并让它实现IRequest<TResponse>接口(这里返回批量添加的ID列表,可根据业务调整返回类型):

public class AddFieldsCommand : IRequest<ServiceResponse<List<int>>>
{
    // 存储批量添加的字段命令集合
    public List<AddFieldCommand> FieldCommands { get; set; } = new List<AddFieldCommand>();
}

2. 编写对应的批量处理器

创建处理AddFieldsCommand的处理器,在Handle方法中实现批量添加逻辑:

public class AddFieldsCommandHandler : IRequestHandler<AddFieldsCommand, ServiceResponse<List<int>>>
{
    private readonly IFieldsService _fieldService;

    public AddFieldsCommandHandler(IFieldsService fieldService)
    {
        _fieldService = fieldService;
    }

    public async Task<ServiceResponse<List<int>>> Handle(AddFieldsCommand request, CancellationToken cancellationToken)
    {
        var addedIds = new List<int>();
        
        // 遍历集合处理单个添加逻辑
        foreach (var fieldCmd in request.FieldCommands)
        {
            var response = await _fieldService.AddField(fieldCmd, cancellationToken);
            if (response.Success)
            {
                addedIds.Add(response.Data);
            }
            // 可根据业务需求处理失败场景:比如中断流程返回错误,或记录错误后继续执行
        }

        return new ServiceResponse<List<int>> 
        { 
            Success = true, 
            Data = addedIds 
        };
    }
}

3. 修改控制器方法

将控制器参数替换为新的聚合请求类,然后通过MediatR发送请求:

public async Task<ActionResult<ServiceResponse<List<int>>>> AddField(AddFieldsCommand objFieldsCommand)
{
    return await _mediator.Send(objFieldsCommand);
}

可选优化:事务处理

如果需要保证批量操作的原子性(要么全部成功,要么全部失败),可以在Handler中引入事务:

// 假设使用EF Core,注入DbContext
private readonly AppDbContext _dbContext;

public AddFieldsCommandHandler(IFieldsService fieldService, AppDbContext dbContext)
{
    _fieldService = fieldService;
    _dbContext = dbContext;
}

public async Task<ServiceResponse<List<int>>> Handle(AddFieldsCommand request, CancellationToken cancellationToken)
{
    using var transaction = await _dbContext.Database.BeginTransactionAsync(cancellationToken);
    try
    {
        var addedIds = new List<int>();
        foreach (var fieldCmd in request.FieldCommands)
        {
            var response = await _fieldService.AddField(fieldCmd, cancellationToken);
            if (!response.Success)
            {
                throw new Exception(response.Message);
            }
            addedIds.Add(response.Data);
        }

        await _dbContext.SaveChangesAsync(cancellationToken);
        await transaction.CommitAsync(cancellationToken);
        
        return new ServiceResponse<List<int>> { Success = true, Data = addedIds };
    }
    catch (Exception ex)
    {
        await transaction.RollbackAsync(cancellationToken);
        return new ServiceResponse<List<int>> { Success = false, Message = ex.Message };
    }
}

内容的提问来源于stack exchange,提问作者Rahul Parab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:33:08