Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix copy observations #1755

Merged
merged 11 commits into from
Dec 12, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- Filtering striae for `not specified` returned wrong results.
- Filtering by `borehole status` did not work.
- When saving with ctrl+s in the borehole sections, the form content was reset.
- When copying a borehole, the nested collections of observations were not copied.
- There was a bug when changing the order, transparency or visibility of custom WMS user layers.
- The borehole status was not translated everywhere in the workflow panel.

Expand Down
140 changes: 90 additions & 50 deletions src/api/Controllers/BoreholeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public async Task<ActionResult<PaginatedBoreholeResponse>> GetAllAsync([FromQuer

var totalCount = await query.CountAsync().ConfigureAwait(false);
var boreholes = await query.Skip(skip).Take(pageSize).ToListAsync().ConfigureAwait(false);

var paginatedResponse = new PaginatedBoreholeResponse(totalCount, pageNumber, pageSize, MaxPageSize, boreholes);

return Ok(paginatedResponse);
Expand All @@ -117,31 +118,6 @@ public async Task<ActionResult<Borehole>> GetByIdAsync(int id)
return Ok(borehole);
}

private IQueryable<Borehole> GetBoreholesWithIncludes()
{
return Context.Boreholes.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerColorCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerDebrisCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerGrainAngularityCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerGrainShapeCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerOrganicComponentCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerUscs3Codes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.LithologicalDescriptions)
.Include(b => b.Stratigraphies).ThenInclude(s => s.FaciesDescriptions)
.Include(b => b.Stratigraphies).ThenInclude(s => s.ChronostratigraphyLayers)
.Include(b => b.Stratigraphies).ThenInclude(s => s.LithostratigraphyLayers)
.Include(b => b.Completions).ThenInclude(c => c.Casings).ThenInclude(c => c.CasingElements)
.Include(b => b.Completions).ThenInclude(c => c.Instrumentations)
.Include(b => b.Completions).ThenInclude(c => c.Backfills)
.Include(b => b.Sections).ThenInclude(s => s.SectionElements)
.Include(b => b.Observations)
.Include(b => b.BoreholeCodelists)
.Include(b => b.Workflows)
.Include(b => b.BoreholeFiles)
.Include(b => b.BoreholeGeometry)
.Include(b => b.Workgroup)
.Include(b => b.UpdatedBy);
}

/// <summary>
/// Asynchronously copies a <see cref="Borehole"/>.
/// </summary>
Expand Down Expand Up @@ -175,31 +151,7 @@ public async Task<ActionResult<int>> CopyAsync([Required] int id, [Required] int
return NotFound();
}

if (borehole.Observations != null)
{
// Include FieldMeasurementResults and HydrotestResults separately since Entity Framework does not support casting in an Include statement
var fieldMeasurements = borehole.Observations.OfType<FieldMeasurement>().ToList();
#pragma warning disable CS8603
// Cannot include null test for fieldMeasurementResults and hydrotestResults since they are not yet loaded
// if there are no fieldMeasurementResults of hydrotestResults the LoadAsync method will be called but have no effect
foreach (var fieldMeasurement in fieldMeasurements)
{
await Context.Entry(fieldMeasurement)
.Collection(f => f.FieldMeasurementResults)
.LoadAsync()
.ConfigureAwait(false);
}

var hydrotests = borehole.Observations.OfType<Hydrotest>().ToList();
foreach (var hydrotest in hydrotests)
{
await Context.Entry(hydrotest)
.Collection(h => h.HydrotestResults)
.LoadAsync()
.ConfigureAwait(false);
}
#pragma warning restore CS8603
}
await LoadObservationDetailsAsync(borehole).ConfigureAwait(false);

// Set ids of copied entities to zero. Entities with an id of zero are added as new entities to the DB.
borehole.Id = 0;
Expand Down Expand Up @@ -293,6 +245,30 @@ await Context.Entry(hydrotest)
hydrotestResult.Id = 0;
}
}

if (hydrotest.HydrotestKindCodes != null)
{
foreach (var hydrotestKindCode in hydrotest.HydrotestKindCodes)
{
hydrotestKindCode.HydrotestId = 0;
}
}

if (hydrotest.HydrotestEvaluationMethodCodes != null)
{
foreach (var hydrotestEvaluationMethodCode in hydrotest.HydrotestEvaluationMethodCodes)
{
hydrotestEvaluationMethodCode.HydrotestId = 0;
}
}

if (hydrotest.HydrotestFlowDirectionCodes != null)
{
foreach (var hydrotestFlowDirectionCode in hydrotest.HydrotestFlowDirectionCodes)
{
hydrotestFlowDirectionCode.HydrotestId = 0;
}
}
}
}

Expand Down Expand Up @@ -326,4 +302,68 @@ await Context.Entry(hydrotest)
if (entity == null) return default;
return await Task.FromResult<int?>(entity.Id).ConfigureAwait(false);
}

private IQueryable<Borehole> GetBoreholesWithIncludes()
{
return Context.Boreholes.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerColorCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerDebrisCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerGrainAngularityCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerGrainShapeCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerOrganicComponentCodes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.Layers).ThenInclude(l => l.LayerUscs3Codes)
.Include(b => b.Stratigraphies).ThenInclude(s => s.LithologicalDescriptions)
.Include(b => b.Stratigraphies).ThenInclude(s => s.FaciesDescriptions)
.Include(b => b.Stratigraphies).ThenInclude(s => s.ChronostratigraphyLayers)
.Include(b => b.Stratigraphies).ThenInclude(s => s.LithostratigraphyLayers)
.Include(b => b.Completions).ThenInclude(c => c.Casings).ThenInclude(c => c.CasingElements)
.Include(b => b.Completions).ThenInclude(c => c.Instrumentations)
.Include(b => b.Completions).ThenInclude(c => c.Backfills)
.Include(b => b.Sections).ThenInclude(s => s.SectionElements)
.Include(b => b.Observations)
.Include(b => b.BoreholeCodelists)
.Include(b => b.Workflows)
.Include(b => b.BoreholeFiles)
.Include(b => b.BoreholeGeometry)
.Include(b => b.Workgroup)
.Include(b => b.UpdatedBy);
}

private async Task LoadObservationDetailsAsync(Borehole borehole)
{
if (borehole.Observations != null)
{
var fieldMeasurements = borehole.Observations.OfType<FieldMeasurement>().ToList();
foreach (var fieldMeasurement in fieldMeasurements)
{
await Context.Entry(fieldMeasurement)
.Collection(f => f.FieldMeasurementResults!)
.LoadAsync()
.ConfigureAwait(false);
}

var hydrotests = borehole.Observations.OfType<Hydrotest>().ToList();
foreach (var hydrotest in hydrotests)
{
await Context.Entry(hydrotest)
.Collection(h => h.HydrotestResults!)
.LoadAsync()
.ConfigureAwait(false);

await Context.Entry(hydrotest)
.Collection(h => h.HydrotestKindCodes!)
.LoadAsync()
.ConfigureAwait(false);

await Context.Entry(hydrotest)
.Collection(h => h.HydrotestEvaluationMethodCodes!)
.LoadAsync()
.ConfigureAwait(false);

await Context.Entry(hydrotest)
.Collection(h => h.HydrotestFlowDirectionCodes!)
.LoadAsync()
.ConfigureAwait(false);
}
danjov marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
2 changes: 1 addition & 1 deletion src/api/Models/Borehole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ public class Borehole : IChangeTracking, IIdentifyable
/// <summary>
/// Gets the <see cref="Borehole"/>'s observations.
/// </summary>
public ICollection<Observation>? Observations { get; }
public ICollection<Observation>? Observations { get; set; }

/// <summary>
/// Gets the <see cref="Borehole"/>'s workflows.
Expand Down
Loading
Loading