EF Core - update fields before SaveChanges () / SaveChangesAsync ()

I'm just learning EF Core and .NET Core MVC in general, so I'm sorry if this question has been covered before - I searched StackOverflow and Microsoft Docs and didn't come up with anything.

A simplified version of my model:

    public class MyModel
    {
        public int Id { get; set; }
        public int ParentId { get; set; }
        public MyModel Parent { get; set; }
        public string Type { get; set; }
        public string Subtype { get; set; }
    }

      

My controller:

    public class MyController : Controller
    {
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit (int? id )
        {
            if ( id == null ) return NotFound();
            var modelToUpdate = await _context.MyModels
                .Include( m => m.Parent )
                .FirstOrDefaultAsync( m => m.Id == id );
            if ( modelToUpdate == null ) return NotFound();

            if ( string.IsNullOrWhitespace(modelToUpdate.Type) )
            {
                modelToUpdate.Type = modelToUpdate.Parent.Type;
            }

            if ( await TryUpdateModelAsync<MyModel>(
                    modelToUpdate,
                    "",
                    m => m.Id, m => m.ParentId, m => m.Type, m => m.Subtype
                ) 
            ) {
                try
                {
                    await _context.SaveChangesAsync();
                }
                catch ( DbUpdateException )
                {
                    ModelState.AddModelError( "", "Unable to save changes" );
                }
                return RedirectToAction("Index");
            }
            return View(modelToUpdate);
        }
    }

      

Installation modelToUpdate.Type

in is modelToUpdate.Parent.Type

not written to the database. Why I am doing this: To improve consistency in the dataset. I could do this client side with AJAX, but I would rather not.

EF recognizes that the Entity has changed, but does not update the database row with the latest value in the controller.

I looked at _context.ChangeTracker

and tried manually:

    _context.Entity(modelToUpdate).State = EntityState.Modified;

      

and with:

    _context.Entity(modelToUpdate).Property( m => m.Type ).CurrentValue = modelToUpdate.Type;

      

and .OriginalValue

, without effect.

When I set a breakpoint in the statement TryUpdateModelAsync()

, it modelToUpdate

shows the correct values. The breakpoint at _context.SaveChangesAsync();

shows instead null

.

It looks like it TryUpdateModelAsync()

uses the original values ​​returned from the view and completely ignores the values ​​I set in the controller in post-processing.

As an added note: I have similar logic for [HttpPost("Create")]

and it works flawlessly, but I am using the following:

    if ( ModelState.IsValid )
    {
        _context.Add(model);
        await _context.SaveChangesAsync();
    }

      

Can anyone please explain what I am missing in state tracking here?

+3


source to share





All Articles