2

I have 2 models in my MVC project.

Assignment:

public class Assignment
{
        public int ID { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public User User { get; set; }
}

User:

public class User
{
        public int ID { get; set; }

        public string Name { get; set; }

        public ICollection<Assignment> Assignments { get; set; }
}

There is a relation "Many to One" between them. One User can have multiple Assignments. Currently I'm working on API Controller and I want to implement an updating method for assigment to be added for particular user.

What I've find out so far is to try out with PATCH method. Here is my code block that isn't working how I want it to.

        [HttpPatch]
        [Route("api/[controller]/{id}")]
        public IActionResult DelegateAssignment(int id, [FromBody]JsonPatchDocument<Assignment> assignmentPatch)
        {
            var assignment = _context.Assignments.Find(id);
            assignmentPatch.ApplyTo(assignment);
            _context.SaveChangesAsync();

            return Ok(assignment);
        }

And the Body im sending through API (testing using Postman):

 [
    {
      "op": "replace",
      "path": "/User",
      "value": {
        "id": 1,
        "name": "User1"
      }
    }
]

However my database is not updating at all. So my question is - what is best way of updating one database table related to the other one (related objects), so both models gets updated (the Assigment will get proper User and the User will have a new item added to Assigments collection). I was thinking also about implementing POST method, but I dont know which version would be the best as a solution. Thanks for helping me out! :)

1
  • You are using an async method ˋSaveChangesAsync()´ in a sinc action. Commented Nov 1, 2018 at 9:53

2 Answers 2

2

Check the issues below in your code:

  • For _context.SaveChangesAsync(); which is async task, you need to add await to wait for it complete
  • Change IActionResult to async Task<IActionResult> to make use of await _context.SaveChangesAsync();.

I'm working on API Controller and I want to implement an updating method for assigment to be added for particular user.

For working code for you, try

        public async Task<IActionResult> DelegateAssignment(int id, [FromBody]JsonPatchDocument<Assignment> assignmentPatch)
    {
        //Option1
        var assignment = _dbContext.Assignment.Include(a => a.User).AsNoTracking().FirstOrDefault(a => a.ID == id);
        assignmentPatch.ApplyTo(assignment);
        _dbContext.Assignment.Update(assignment);
        return Ok(assignment);
    }

But, if you want to add/update the Assignment to the specific User by JsonPatchDocument<Assignment>, I suggest you try add UserID property to Assignment, and then change the UserID instead of User.

  • Assignment

    public class Assignment
    {
       public int ID { get; set; }
    
       public string Name { get; set; }
    
       public string Description { get; set; }
    
       public int UserID { get; set; }
    
       public User User { get; set; }
    }
    
  • Json Request

    [
      {
        "op": "replace",
        "path": "/UserID",
        "value": 1
      }
    ]
    
  • Controller

        public async Task<IActionResult> DelegateAssignment(int id, [FromBody]JsonPatchDocument<Assignment> assignmentPatch)
    {          
    
        //Option2
        var assignment = _dbContext.Assignment.Find(id);
        assignmentPatch.ApplyTo(assignment);
    
        await _dbContext.SaveChangesAsync();
    
        return Ok(assignment);
    }
    
Sign up to request clarification or add additional context in comments.

1 Comment

Hello. Thanks for an answer. However the problem was without lack of "include" inside the LINQ query. EF Core uses eager loading and it needs this method to be called while querying to the database table related to the other one. Now everything works like a charm!
1

Just a heads up, the issue you're having here has nothing to do with the HTTP method - POST, PATCH etc. are just standards that provide useful information to outside users what sort of operation your API is doing. They don't change the way your code works.

Regarding your issue:

var assignment = _context.Assignments.Find(id);

The first thing to do would be to check whether this operation is actually retrieving an entity. Debug your code and check to see whether 'assignment' is null or not.

Also, just to check, are you encountering any exceptions?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.