Use of AsNoTracking in ASP.Net Core docs

c# entity-framework entity-framework-core

Question

I've been trying to understand the use of AsNoTracking when editing an entity in the following code from ASP.Net Core docs, found here:

public async Task<IActionResult> OnPostAsync(int id)
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    // Fetch Contact from DB to get OwnerID.
    var contact = await Context
        .Contact.AsNoTracking()
        .FirstOrDefaultAsync(m => m.ContactId == id);

    if (contact == null)
    {
        return NotFound();
    }

    var isAuthorized = await AuthorizationService.AuthorizeAsync(
                                             User, contact,
                                             ContactOperations.Update);
    if (!isAuthorized.Succeeded)
    {
        return new ChallengeResult();
    }

    Contact.OwnerID = contact.OwnerID;

    Context.Attach(Contact).State = EntityState.Modified;

    …

    await Context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

The summary for AsNoTracking states:

Disabling change tracking is useful for read-only scenarios because it avoids the overhead of setting up change tracking for each entity instance. You should not disable change tracking if you want to manipulate entity instances and persist those changes to the database using Microsoft.EntityFrameworkCore.DbContext.SaveChanges.

Clearly this isn't a read-only scenario and the only reason this method is running is to attempt to update the entity in the database.

Is there an explanation for why this code seems to be going against the advice given in the AsNoTracking summary?

1
3
12/5/2018 4:32:57 PM

Popular Answer

The fact that AsNoTracking() is used when fetching the Contact instance is also the reason why the contact gets reattached back to the context with it's State set to EntityState.Modified - as contact is not tracked by the context, you need to explicitly let the context know that this entity has been modified.

If AsNoTracking() was not used, that wouldn't be needed.

NoTracking Queries (MS Docs)

Generally, you benefit from AsNoTracking() in read-only scenarios (the R part of CRUD)

As for the potential intent of the use of AsNoTracking() in the snippet, @Panagiotis Kanavos's comment is IMHO spot on:

"I think I understand the "cleverness" here - the contact is loaded without tracking to reduce overhead if Update isn't authorized. If it is, the object is reattached and an attempt to Approve is made. Depending on that status, its final status is updated and finally saved."

3
12/5/2018 4:55:08 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow