using AutobusApi.Application.Common.Exceptions; using AutobusApi.Application.Common.Interfaces; using AutobusApi.Domain.Entities; using MediatR; using Microsoft.EntityFrameworkCore; namespace AutobusApi.Application.Routes.Commands.UpdateRoute; public class UpdateRouteCommandHandler : IRequestHandler { private readonly IApplicationDbContext _dbContext; public UpdateRouteCommandHandler(IApplicationDbContext dbContext) { _dbContext = dbContext; } public async Task Handle( UpdateRouteCommand request, CancellationToken cancellationToken) { var route = await _dbContext.Routes .Include(r => r.RouteAddresses) .SingleAsync(r => r.Id == request.Id, cancellationToken); if (route == null) { throw new NotFoundException(); } var compaper = new RouteAddressEqualityComparer(); var routeAddressesToBeRemoved = route.RouteAddresses .ExceptBy(request.Addresses.Select( a => new RouteAddress { AddressId = a.Id, Order = a.Order }), ra => new RouteAddress { AddressId = ra.AddressId, Order = ra.Order }, compaper ).ToList(); var remainingRouteAddresses = route.RouteAddresses .ExceptBy(routeAddressesToBeRemoved.Select( ratbr => new RouteAddress { AddressId = ratbr.AddressId, Order = ratbr.Order }), ra => new RouteAddress { AddressId = ra.AddressId, Order = ra.Order }, compaper ).ToList(); var newRouteAddresses = remainingRouteAddresses .UnionBy(request.Addresses.Select( a => new RouteAddress { AddressId = a.Id, Order = a.Order }), rra => new RouteAddress { AddressId = rra.AddressId, Order = rra.Order }, compaper ).ToList(); route.RouteAddresses = newRouteAddresses.ToList(); await _dbContext.SaveChangesAsync(cancellationToken); } private class RouteAddressEqualityComparer : IEqualityComparer { public bool Equals(RouteAddress? x, RouteAddress? y) { return x?.AddressId == y?.AddressId && x?.Order == y?.Order; } public int GetHashCode(RouteAddress obj) { return obj.AddressId.GetHashCode() + obj.Order.GetHashCode(); } } }