2026-06-23 19:03:31 +01:00

157 lines
5.3 KiB
C#

using Microsoft.EntityFrameworkCore;
using Solicitors.Core;
using Solicitors.Core.Data;
using Solicitors.Core.Models;
using Solicitors.Core.Models.Imports;
using Solicitors.Data.RepositorySetup;
namespace Solicitors.Data;
internal class SolicitorsRepository : DbContext, ISolicitorRepository, IReadOnlyCitiesRepository, IRatingsProviderRepository
{
private readonly IRepoSetupService _setup;
public SolicitorsRepository(IRepoSetupService setup)
{
_setup = setup;
}
public DbSet<Solicitor> Solicitors { get; set; }
public DbSet<SolicitorRating> SolicitorRatings { get; set; }
public DbSet<SolicitorLocation> SolicitorLocations { get; set; }
public DbSet<SolicitorLocationRating> SolicitorLocationRatings { get; set; }
public DbSet<City> Cities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> _setup.OnConfiguring(optionsBuilder);
public IAsyncEnumerable<Solicitor> GetAllSolicitorsAsync()
=> Solicitors
.Include(solicitor => solicitor.Cities)
.Include(solicitor => solicitor.Locations)
.ThenInclude(location => location.LocationRatings)
.Include(solicitor => solicitor.Ratings)
.AsAsyncEnumerable();
public Task<Solicitor?> GetSolicitorByIdAsync(Guid id, CancellationToken cancellationToken = default)
=> Solicitors
.Include(solicitor => solicitor.Cities)
.Include(solicitor => solicitor.Locations)
.ThenInclude(location => location.LocationRatings)
.Include(solicitor => solicitor.Ratings)
.FirstOrDefaultAsync(x => x.SolicitorId == id, cancellationToken);
public async Task AddOrUpdateSolicitorAsync(SolicitorData solicitor, CancellationToken cancellationToken)
{
var matchingSolicitor = await Solicitors
.FirstOrDefaultAsync(
item => item.Name == solicitor.Name,
cancellationToken: cancellationToken);
if (matchingSolicitor is null)
await AddNewSolicitor(solicitor, cancellationToken);
else
await UpdateExistingSolicitor(solicitor, matchingSolicitor, cancellationToken);
}
private async Task AddNewSolicitor(
SolicitorData solicitor,
CancellationToken cancellationToken)
{
var newSol = new Solicitor()
{
Name = solicitor.Name,
RelativeUrl = solicitor.UrlPath,
Phone = solicitor.Phone,
Email = solicitor.Email,
Website = solicitor.Website,
ShortDescription = solicitor.ShortDescription
};
Solicitors.Add(newSol);
var cityTasks = solicitor.Cities
.Distinct()
.Select(async (city) =>
{
var matchingCity = await Cities.FirstOrDefaultAsync(
item => item.Name == city,
cancellationToken: cancellationToken);
if (matchingCity is null)
{
matchingCity = new City() { Name = city };
Cities.Add(matchingCity);
newSol.Cities.Add(matchingCity);
}
matchingCity.Solicitors.Add(newSol);
});
await Task.WhenAll(cityTasks);
foreach (var rating in solicitor.Ratings)
{
var newRating = new SolicitorRating()
{
Value = rating.Value,
Maximum = rating.MaxValue,
Provider = rating.RatingProvider,
Solicitor = newSol
};
SolicitorRatings.Add(newRating);
newSol.Ratings.Add(newRating);
}
foreach (var location in solicitor.Offices)
{
var newLocation = new SolicitorLocation()
{
Address = location.Address,
Phone = location.Phone,
Solicitor = newSol
};
SolicitorLocations.Add(newLocation);
newSol.Locations.Add(newLocation);
foreach (var rating in location.LocationRatings)
{
var newLocRating = new SolicitorLocationRating()
{
Value = rating.value,
Maximum = rating.MaxValue,
Provider = rating.RatingProvider,
SolicitorLocation = newLocation
};
SolicitorLocationRatings.Add(newLocRating);
newLocation.LocationRatings.Add(newLocRating);
}
}
await SaveChangesAsync(cancellationToken);
}
private Task UpdateExistingSolicitor(
SolicitorData solicitor,
Solicitor matchingSolicitor,
CancellationToken cancellationToken)
{
// TODO
return Task.CompletedTask;
}
public IAsyncEnumerable<string> GetCitiesAsync(CancellationToken cancellationToken)
{
return Cities
.Select(city => city.Name)
.AsAsyncEnumerable();
}
public IAsyncEnumerable<string> GetAllRatingsProvidersAsync()
{
return SolicitorRatings
.Select(rating => rating.Provider)
.Distinct()
.OrderBy(x => x == "Solicitors.com" ? 0 : 1)
.ThenBy(x => x)
.AsAsyncEnumerable();
}
}