157 lines
5.3 KiB
C#
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();
|
|
}
|
|
} |