Home > Back-end >  Deleting multiple IDs with MediatR Controller
Deleting multiple IDs with MediatR Controller

Time:11-02

Pretty straightforward question. I want to be able to delete multiple IDs, just like the example below.

public async Task<ActionResult> Delete(List<int> id)`

Snippet

[HttpDelete("{id:int}")]
public async Task<ActionResult> Delete(int id)
{
    await Mediator.Send(new DeleteRoomCommand { Id = id }).ConfigureAwait(false);

    return NoContent();
}

public class DeleteRoomCommand : IRequest
{
    public long Id { get; set; }
}

public class DeleteRoomCommandHandler : IRequestHandler<DeleteRoomCommand>
{
    private readonly IApplicationDbContext _context;

    public DeleteRoomCommandHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<Unit> Handle(DeleteRoomCommand request, CancellationToken cancellationToken)
    {
        var entity = await _context.Rooms.FindAsync(request.Id).ConfigureAwait(false);

        if (entity == null)
        {
            throw new NotFoundException(nameof(Room), request.Id);
        }

        _context.Rooms.Remove(entity);

        await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

        return Unit.Value;
    }
}

CodePudding user response:

You seem to be asking two questions:

  1. How do I write a new command and handler for MediatR that will accept and pass an enumerable of IDs instead of just one?

  2. How do I write a DbContext call to handle that enumerable?

The IRequest object is just a simple class that contains the data you need to process it. You can create a new pluralized command class that accepts an enumerable of IDs, and a new handler designed to handle that case. You'll need to tweak this based on your own testing.

public class DeleteRoomsCommand : IRequest
{
    public IEnumerable<long> Ids { get; set; }
}

public class DeleteRoomsCommandHandler : IRequestHandler<DeleteRoomsCommand>
{
    private readonly IApplicationDbContext _context;

    public DeleteRoomCommandHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<Unit> Handle(DeleteRoomsCommand request, CancellationToken cancellationToken)
    {
        var entities = await _context.Rooms.Where(r => request.Ids.Contains(r.Id)); // .ConfigureAwait(false);

        _context.Rooms.RemoveRange(entities);

        await _context.SaveChangesAsync(cancellationToken); // .ConfigureAwait(false);

        return Unit.Value;
    }
}

Your new call is instantiated the same, taking the IDs received by your controller and assigning them to a new MediatR command:

await Mediator.Send(new DeleteRoomsCommand { Ids = ids }); //.ConfigureAwait(false);

Your new method could accept the list of IDs via query parameter or via the body, depending on your need or convention.

  • Related