EL GHAZAL Said
EL GHAZAL Said

Reputation: 1

How to Patch Multiple Objects in a Table Simultaneously Using ASP.NET Core Web API

I am working on an ASP.NET Core Web API project and need to update multiple columns for multiple rows within a single HTTP PATCH request. I am familiar with using JsonPatchDocument to update a single object, but I am unsure how to extend this to handle updating multiple objects in the same table at once.

Here is what I am trying to achieve:

I have a table with multiple rows that need to be updated. Each row can have multiple columns that need to be changed. I want to send a single PATCH request to update these rows and columns.

public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public DateTime CountDate { get; set; }
}

The collection i am sending by Postman:

[
  {
    "id": 4,
    "changes": {
        "Name": "Test",
        "Code": "ICO3",
        "CountDate": "2024-06-25T11:00:00"
    }
  },
  {
    "id": 6,
    "changes": {
        "Name": "Test",
        "Code": "ICO9",
        "CountDate": "2024-06-25T11:00:00"
    }
  }
]

the normal Patch method for handling one request:

[HttpPatch("{id}")]
public IActionResult PatchEntity(int id, [FromBody] JsonPatchDocument<MyEntity> patchDoc)
{
    if (patchDoc == null)
    {
        return BadRequest();
    }

    var entity = _context.MyEntities.Find(id);
    if (entity == null)
    {
        return NotFound();
    }

    patchDoc.ApplyTo(entity, ModelState);

    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    _context.SaveChanges();

    return NoContent();
}

custom Patch that i made:

    [HttpPost("Batch")]
    public virtual async Task<IActionResult> Batch([FromBody] Dictionary<int, Delta<T>> objs)
    {
        var errors = new List<string>();
        var responses = new List<object>();

        foreach (var kvp in objs)
        {
            try
            {
                // Ensure entity exists
                var entity = await _context.T.FindAsync(kvp.Key);
                if (entity == null)
                {
                    errors.Add($"Object with ID {kvp.Key} not found.");
                    continue;
                }

                // Apply patch
                kvp.Value.Patch(entity);

                // Validate model state
                if (!TryValidateModel(entity))
                {
                    errors.Add($"Invalid model state for object with ID {kvp.Key}.");
                    continue;
                }

                // Save changes
                await _context.SaveChangesAsync();
                responses.Add(new { Id = kvp.Key, Success = true });
            }
            catch (Exception ex)
            {
                errors.Add($"Failed to patch object with ID {kvp.Key}: {ex.Message}");
            }
        }

        if (errors.Any())
        {
            return BadRequest(errors);
        }

        return Ok(responses);
    }

when i check the delta object, the _changedProperties is always 0

Question:

How can I extend this approach to handle a single PATCH request that updates multiple rows and multiple columns in the same table? Ideally, I would like to ensure that all updates are applied in a single transaction.

Any advice or examples on how to achieve this would be greatly appreciated!

Upvotes: 0

Views: 93

Answers (0)

Related Questions