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?
source to share
No one has answered this question yet
Check out similar questions: