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

PIMS-1220, PIMS-1221, PIMS-1222 #88

Merged
merged 2 commits into from
Mar 27, 2020

Conversation

devinleighsmith
Copy link
Contributor

Automap Evaluations
Move logic from controller to DAL

entity.UpdatedOn = DateTime.UtcNow;

this.Context.Parcels.Update(entity);
//Add/Update a parcel and all child collections
Copy link
Contributor Author

@devinleighsmith devinleighsmith Mar 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this entire 60ish block could be replaced by:
context.Update(rootEntity);
context.SaveChanges();
which handles "Upserting" the parent and all child entities, supporting mixing and matching adding new entities and updating existing entities. The problem is that "Upserting" does not support deletes. My original thought was that I could messily handle the deletes by loading the existing parcel and then disposing it after so I could use Context.Update (can only attach one unique entity in a context at a time). However, the concept of detaching entities with their children is not supported as of this time. dotnet/efcore#18406

Only solution at this time is to not handle any kinds of delete operations in this update function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not supporting delete here makes the most sense presently.

@@ -67,6 +67,7 @@ public IActionResult GetParcels()
/// <returns></returns>
[HttpPost]
[HasPermission(Permissions.PropertyView)]
[Route("/api/parcels/filter")]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't have two posts with the same route. @Fosol let me know if this is a breaking change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fine, these aren't used yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that there can be no two POST on the same route. But with this change it is now confusing to the API consumer how to filter parcels. There's now two (different) routes to do it:

  • GET /api/parcels?field1=value1&field2=value2
  • POST /api/parcels/filter/ with a body of { field1: value1, ...}

I know the POST is there for convenience but I rather remove the [HttpPost] attribute and let it be a GET only operation. Note that I'm not saying we discard the whole GetParcels(filter) function, just not exposing it via HTTP

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is outside the scope of this review since I think you had the same issue with the GET/POST before I was forced to rename it. Feel free to discuss that here but I'm not planning on changing anything at this time.

Copy link
Contributor

@Fosol Fosol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple minor changes.

@@ -67,6 +67,7 @@ public IActionResult GetParcels()
/// <returns></returns>
[HttpPost]
[HasPermission(Permissions.PropertyView)]
[Route("/api/parcels/filter")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fine, these aren't used yet.

// get entries that are being Added or Updated
var modifiedEntries = ChangeTracker.Entries()
.Where(x => (x.State == EntityState.Added || x.State == EntityState.Modified));
var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have access to the extension method User.GetUserId()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, right. let me see.

entity.CreatedById = new Guid(userId);
entity.CreatedOn = DateTime.UtcNow;
}
entity.UpdatedById = new Guid(userId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't do this if it's a EntityState.Delete as it will most likely confuse EF with related properties.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, updating.

.Include(p => p.Evaluations)
.Include(p => p.Buildings).ThenInclude(b => b.Evaluations)
.Include(p => p.Buildings).ThenInclude(b => b.Address)
.SingleOrDefault(u => u.Id == parcel.Id) ?? throw new KeyNotFoundException();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should change to FirstOrDefault(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't know, I kind of like the documented behaviour of this when we are searching for a unique key:

Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence.

seems appropriate since there should never be more than one match.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the end of the day it doesn't change much here. As the LINQ statement becomes an SQL statement and if it returns more than one it would throw an error. However since you're making a request for the primary key there never will be more than one or none returned. So using Single technically is doing more work than is required.

entity.UpdatedOn = DateTime.UtcNow;

this.Context.Parcels.Update(entity);
//Add/Update a parcel and all child collections
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not supporting delete here makes the most sense presently.

@asanchezr
Copy link
Contributor

Couple of comments re: process.

  • The title of this PR is PIMS-976 but I can't seem to find that issue in JIRA. A more descriptive title would help me understand what I should be reviewing
  • The PR "source" branch is named PIMS-1220 which doesn't match the issue number of the PR title so I'm a bit lost what this PR is about. PIMS-1220 is about single parcel GET and I see a lot of changes related to creating, updating and deleting parcels...

@asanchezr asanchezr closed this Mar 27, 2020
@asanchezr asanchezr reopened this Mar 27, 2020
Fosol
Fosol previously approved these changes Mar 27, 2020
@devinleighsmith
Copy link
Contributor Author

@asanchezr Agreed. I messed up the commit message on this one, I'm not in any rush so I'll correct it.

Also I ended up doing all three API stories at the same time. Theoretically I'd rather have submitted a PR for each one separately. However, realistically I updated all three at the same time as

  1. I was using the API outputs to test the inputs, so as I updated one API I often found/resolved issues in the others.
  2. There were some foundational changes required by all three APIs.

I'm also really annoyed that Github doesn't allow me to respond directly to your comment above. Why Github, Why?

Smith added 2 commits March 27, 2020 12:21
Automap Evaluations
Move logic from controller to DAL
Rewrite DAL logic to be less verbose, support direct write of automapper
entities.
@devinleighsmith devinleighsmith changed the title PIMS-976 PIMS-1220, PIMS-1221, PIMS-1222 Mar 27, 2020
@devinleighsmith devinleighsmith merged commit dc3b655 into bcgov:dev Mar 27, 2020
Fosol pushed a commit to Fosol/PIMS that referenced this pull request May 8, 2020
* PIMS-1220, PIMS-1221, PIMS-1222
Automap Evaluations
Move logic from controller to DAL
Rewrite DAL logic to be less verbose, support direct write of automapper
entities.

* code review comments

Co-authored-by: Smith <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants