Skip to content

Commit

Permalink
Merge pull request #1 from elarson42/elarson/net8-3
Browse files Browse the repository at this point in the history
Elarson/net8 3
  • Loading branch information
zlannin authored Oct 15, 2024
2 parents c05e5a6 + 8dd9ff9 commit 1931d2e
Show file tree
Hide file tree
Showing 48 changed files with 643 additions and 643 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace WesternStatesWater.WestDaat.Accessors.Extensions
{
public static class EnumerableExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this IAsyncEnumerable<T> asyncEnumerable)
{
var enumerator = asyncEnumerable.GetAsyncEnumerator();
try
{
while (enumerator.MoveNextAsync().AsTask().GetAwaiter().GetResult())
{
yield return enumerator.Current;
}
}
finally
{
enumerator.DisposeAsync().AsTask().GetAwaiter().GetResult();
}
}
}
}
27 changes: 10 additions & 17 deletions src/API/WesternStatesWater.WestDaat.Accessors/SiteAccessor.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Data;
using WesternStatesWater.WestDaat.Accessors.EntityFramework;
using WesternStatesWater.WestDaat.Accessors.Mapping;
using WesternStatesWater.WestDaat.Common;
using WesternStatesWater.WestDaat.Common.DataContracts;

namespace WesternStatesWater.WestDaat.Accessors
Expand All @@ -20,7 +18,7 @@ public SiteAccessor(ILogger<SiteAccessor> logger, IDatabaseContextFactory databa

async Task<Site> ISiteAccessor.GetSiteByUuid(string siteUuid)
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
return await db.SitesDim
.Where(x => x.SiteUuid == siteUuid)
.ProjectTo<Site>(DtoMapper.Configuration)
Expand All @@ -29,8 +27,7 @@ async Task<Site> ISiteAccessor.GetSiteByUuid(string siteUuid)

async Task<SiteDigest> ISiteAccessor.GetSiteDigestByUuid(string siteUuid)
{
using var db = _databaseContextFactory.Create();

await using var db = _databaseContextFactory.Create();
return await db.SitesDim
.Where(x => x.SiteUuid == siteUuid)
.ProjectTo<SiteDigest>(DtoMapper.Configuration)
Expand All @@ -48,7 +45,7 @@ async Task<List<Site>> ISiteAccessor.GetSites()

public async Task<SiteDetails> GetSiteDetailsByUuid(string siteUuid)
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
return await db.SitesDim
.Where(x => x.SiteUuid == siteUuid)
.ProjectTo<SiteDetails>(DtoMapper.Configuration)
Expand All @@ -57,26 +54,25 @@ public async Task<SiteDetails> GetSiteDetailsByUuid(string siteUuid)

async Task<SiteLocation> ISiteAccessor.GetWaterSiteLocationByUuid(string siteUuid)
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
return await db.SitesDim.Where(x => x.SiteUuid == siteUuid)
.ProjectTo<SiteLocation>(DtoMapper.Configuration)
.SingleAsync();
}

public async Task<List<WaterSourceInfoListItem>> GetWaterSiteSourceInfoListByUuid(string siteUuid)
{
using var db = _databaseContextFactory.Create();

await using var db = _databaseContextFactory.Create();
return await db.SitesDim.Where(x => x.SiteUuid == siteUuid)
.SelectMany(x => x.WaterSourceBridgeSitesFact
.SelectMany(x => x.WaterSourceBridgeSitesFact
.Select(a => a.WaterSource))
.ProjectTo<WaterSourceInfoListItem>(DtoMapper.Configuration)
.ToListAsync();
.ProjectTo<WaterSourceInfoListItem>(DtoMapper.Configuration)
.ToListAsync();
}

public async Task<List<WaterRightInfoListItem>> GetWaterRightInfoListByUuid(string siteUuid)
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
return await db.AllocationAmountsFact
.Where(x => x.AllocationBridgeSitesFact.Any(y => y.Site.SiteUuid == siteUuid))
.ProjectTo<WaterRightInfoListItem>(DtoMapper.Configuration)
Expand All @@ -95,10 +91,7 @@ public IEnumerable<GeoConnex> GetJSONLDData()
SiteName = a.SiteName,
});

foreach (var geoConnexItem in query)
{
yield return geoConnexItem;
}
return query;
}
}
}
34 changes: 16 additions & 18 deletions src/API/WesternStatesWater.WestDaat.Accessors/SystemAccessor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Data;
using WesternStatesWater.WestDaat.Accessors.EntityFramework;
using WesternStatesWater.WestDaat.Accessors.Mapping;
using WesternStatesWater.WestDaat.Common.DataContracts;
Expand All @@ -19,8 +18,7 @@ public SystemAccessor(ILogger<SystemAccessor> logger, IDatabaseContextFactory da

async Task<List<BeneficialUseItem>> ISystemAccessor.GetAvailableBeneficialUseNormalizedNames()
{
using var db = _databaseContextFactory.Create();

await using var db = _databaseContextFactory.Create();
return await db.BeneficialUsesCV
.ProjectTo<BeneficialUseItem>(DtoMapper.Configuration)
.Distinct()
Expand All @@ -32,32 +30,32 @@ async Task<List<BeneficialUseItem>> ISystemAccessor.GetAvailableBeneficialUseNor

async Task<List<string>> ISystemAccessor.GetAvailableWaterSourceTypeNormalizedNames()
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
return await db.WaterSourceType
.Select(a => a.WaDEName.Length > 0 ? a.WaDEName : a.Name)
.Distinct()
.OrderBy(a => a)
.ToListAsync();
.Select(a => a.WaDEName.Length > 0 ? a.WaDEName : a.Name)
.Distinct()
.OrderBy(a => a)
.ToListAsync();
}

async Task<List<string>> ISystemAccessor.GetAvailableOwnerClassificationNormalizedNames()
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
return await db.OwnerClassificationCv
.Select(a => a.WaDEName.Length > 0 ? a.WaDEName : a.Name)
.Distinct()
.OrderBy(a => a)
.ToListAsync();
.Select(a => a.WaDEName.Length > 0 ? a.WaDEName : a.Name)
.Distinct()
.OrderBy(a => a)
.ToListAsync();
}

async Task<List<string>> ISystemAccessor.GetAvailableStateNormalizedNames()
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
return await db.State
.Select(a => a.WaDEName.Length > 0 ? a.WaDEName : a.Name)
.Distinct()
.OrderBy(a => a)
.ToListAsync();
.Select(a => a.WaDEName.Length > 0 ? a.WaDEName : a.Name)
.Distinct()
.OrderBy(a => a)
.ToListAsync();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
using Microsoft.Extensions.Logging;
using NetTopologySuite.Geometries;
using System.Collections.Concurrent;
using System.Data;
using System.Transactions;
using NetTopologySuite.Geometries.Utilities;
using WesternStatesWater.WestDaat.Accessors.CsvModels;
using WesternStatesWater.WestDaat.Accessors.EntityFramework;
using WesternStatesWater.WestDaat.Accessors.Extensions;
using WesternStatesWater.WestDaat.Accessors.Mapping;
using WesternStatesWater.WestDaat.Common.Configuration;
using WesternStatesWater.WestDaat.Common.DataContracts;
Expand All @@ -31,10 +32,10 @@ public WaterAllocationAccessor(ILogger<WaterAllocationAccessor> logger, IDatabas
public async Task<AnalyticsSummaryInformation[]> GetAnalyticsSummaryInformation(WaterRightsSearchCriteria searchCriteria)
{
using var ts = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled);
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();

// db.database does not pick up transaction from transactionScope if we do not open connection
db.Database.OpenConnection();
await db.Database.OpenConnectionAsync();
var predicate = BuildWaterRightsSearchPredicate(searchCriteria, db);

var analyticsSummary = await db.AllocationAmountsFact
Expand All @@ -61,46 +62,39 @@ public async Task<AnalyticsSummaryInformation[]> GetAnalyticsSummaryInformation(
public async Task<Geometry> GetWaterRightsEnvelope(WaterRightsSearchCriteria searchCriteria)
{
using var ts = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled);
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();

// db.database does not pick up transaction from transactionScope if we do not open connection
db.Database.OpenConnection();
await db.Database.OpenConnectionAsync();
var predicate = BuildWaterRightsSearchPredicate(searchCriteria, db);

//EF Core 7 is supposed to support geometry::EnvelopeAggregate (https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/whatsnew#spatial-aggregate-functions).
//It does work with the basic style that is referenced in the docs.
//However, as soon as you try to aggregate with a SelectMany or nested queries, it either fails to translate or pulls all records into memory and performs the aggregation locally (without erroring which is weird).
//Thus, we hack this together instead. Hopefully EF gets better at translating these aggregates and we can go back to more native EF methods.
var siteIdsCommand = db.AllocationAmountsFact
// Get SiteIds based on search predicate
var siteIds = db.AllocationAmountsFact
.AsNoTracking()
.Where(predicate)
.SelectMany(a => a.AllocationBridgeSitesFact.Select(b => b.SiteId))
.CreateDbCommand();

siteIdsCommand.CommandText = "select geometry::EnvelopeAggregate(coalesce(geometry, sitepoint)).ToString() Geometry " +
"from core.Sites_Dim sdf " +
$"where sdf.SiteId in ({siteIdsCommand.CommandText})";
.SelectMany(a => a.AllocationBridgeSitesFact.Select(b => b.SiteId));

object[] parameters = new object[siteIdsCommand.Parameters.Count];
for (var i = 0; i < siteIdsCommand.Parameters.Count; i++)
{
parameters[i] = siteIdsCommand.Parameters[i];
}
// Retrieve geometries based on the SiteIds
var geometries = db.SitesDim
.AsNoTracking()
.Where(sdf => siteIds.Contains(sdf.SiteId))
.Select(sdf => sdf.Geometry ?? sdf.SitePoint);

var geometry = (await siteIdsCommand.ExecuteScalarAsync()) as string;
// Combine geometries using EnvelopeCombiner
var geometry = EnvelopeCombiner.CombineAsGeometry(geometries);

ts.Complete();

return GeometryHelpers.GetGeometryByWkt(geometry);
return geometry.IsEmpty ? null : GeometryHelpers.GetGeometryByWkt(geometry.ToString());
}

public async Task<WaterRightsSearchResults> FindWaterRights(WaterRightsSearchCriteria searchCriteria, int pageNumber)
{
using var ts = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled);
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();

// db.database does not pick up transaction from transactionScope if we do not open connection
db.Database.OpenConnection();
await db.Database.OpenConnectionAsync();
var predicate = BuildWaterRightsSearchPredicate(searchCriteria, db);

var waterRightDetails = await db.AllocationAmountsFact
Expand Down Expand Up @@ -264,10 +258,10 @@ public Organization GetWaterAllocationAmountOrganizationById(long allocationAmou
{
using var db = _databaseContextFactory.Create();
var org = db.AllocationAmountsFact
.Where(a => a.AllocationAmountId == allocationAmountId)
.Select(a => a.Organization)
.ProjectTo<Organization>(DtoMapper.Configuration)
.Single();
.Where(a => a.AllocationAmountId == allocationAmountId)
.Select(a => a.Organization)
.ProjectTo<Organization>(DtoMapper.Configuration)
.Single();

return org;
}
Expand All @@ -285,21 +279,21 @@ public async Task<List<SiteInfoListItem>> GetWaterRightSiteInfoById(string alloc
{
using var db = _databaseContextFactory.Create();
return await db.AllocationBridgeSitesFact
.Where(x => x.AllocationAmount.AllocationUuid == allocationUuid)
.Select(x => x.Site)
.ProjectTo<SiteInfoListItem>(DtoMapper.Configuration)
.ToListAsync();
.Where(x => x.AllocationAmount.AllocationUuid == allocationUuid)
.Select(x => x.Site)
.ProjectTo<SiteInfoListItem>(DtoMapper.Configuration)
.ToListAsync();
}

public async Task<List<WaterSourceInfoListItem>> GetWaterRightSourceInfoById(string allocationUuid)
{
using var db = _databaseContextFactory.Create();
return await db.AllocationBridgeSitesFact.Where(x => x.AllocationAmount.AllocationUuid == allocationUuid)
.SelectMany(x => x.Site.WaterSourceBridgeSitesFact
.SelectMany(x => x.Site.WaterSourceBridgeSitesFact
.Select(a => a.WaterSource))
.ProjectTo<WaterSourceInfoListItem>(DtoMapper.Configuration)
.Distinct()
.ToListAsync();
.ProjectTo<WaterSourceInfoListItem>(DtoMapper.Configuration)
.Distinct()
.ToListAsync();
}

public async Task<List<AllocationAmount>> GetAllWaterAllocations()
Expand All @@ -317,16 +311,16 @@ public async Task<List<SiteLocation>> GetWaterRightSiteLocationsById(string allo
{
using var db = _databaseContextFactory.Create();
return await db.AllocationBridgeSitesFact
.Where(x => x.AllocationAmount.AllocationUuid == allocationUuid)
.Select(x => x.Site)
.Where(x => x.Longitude.HasValue && x.Latitude.HasValue)
.ProjectTo<SiteLocation>(DtoMapper.Configuration)
.ToListAsync();
.Where(x => x.AllocationAmount.AllocationUuid == allocationUuid)
.Select(x => x.Site)
.Where(x => x.Longitude.HasValue && x.Latitude.HasValue)
.ProjectTo<SiteLocation>(DtoMapper.Configuration)
.ToListAsync();
}

public async Task<List<WaterRightsDigest>> GetWaterRightsDigestsBySite(string siteUuid)
{
using var db = _databaseContextFactory.Create();
await using var db = _databaseContextFactory.Create();
db.Database.SetCommandTimeout(int.MaxValue);
return await db.AllocationAmountsFact
.Where(x => x.AllocationBridgeSitesFact.Any(y => y.Site.SiteUuid == siteUuid))
Expand Down Expand Up @@ -373,6 +367,7 @@ private async IAsyncEnumerable<WaterAllocations> BuildWaterAllocationsModel(Wate
yield return allocation.Map<WaterAllocations>();
}
}

private async IAsyncEnumerable<Sites> BuildSitesModel(WaterRightsSearchCriteria searchCriteria)
{
var (db, filteredSites) = GetFilteredSites(searchCriteria);
Expand Down Expand Up @@ -427,15 +422,14 @@ internal IEnumerable<WaterSources> GetWaterSources(WaterRightsSearchCriteria sea
.AsEnumerable();
}

internal IEnumerable<PodSiteToPouSiteRelationships> GetPodSiteToPouSiteRelationships(WaterRightsSearchCriteria searchCriteria)
private IEnumerable<PodSiteToPouSiteRelationships> GetPodSiteToPouSiteRelationships(WaterRightsSearchCriteria searchCriteria)
{
var (db, filteredSites) = GetFilteredSites(searchCriteria);

return db.PODSiteToPOUSiteFact
.AsNoTracking()
.Where(a => filteredSites
.Any(b => b.SiteId == a.PODSiteId)
|| filteredSites.Any(b => b.SiteId == a.POUSiteId))
.Where(a => filteredSites.Any(b => b.SiteId == a.PODSiteId)
|| filteredSites.Any(b => b.SiteId == a.POUSiteId))
.ProjectTo<PodSiteToPouSiteRelationships>(DtoMapper.Configuration)
.AsEnumerable();
}
Expand Down
Loading

0 comments on commit 1931d2e

Please sign in to comment.