1

I'm new to Identity, EF6, and SQL databases. Please bear with me.

The idea is this: For each user in the database, change a user variable, and save that user. However, I must be going about it incorrectly, as I trip an InvalidOperationException (the infamous: Attaching an entity of type 'Models.ApplicationUser' failed because another entity of the same type already has the same primary key value.)

var _db = new ApplicationDbContext();

IQueryable<ApplicationUser> query = _db.Users; // from IdentityDbContext

// search for matching user
List<ApplicationUser> subordinates = query.Where(p => (p.ParentId == userEmployeeId)).ToList();

if (subordinates != null)
{
  foreach (var sub in subordinates)
  {
    sub.Nickname = "Scooby"; // change an example test variable

    IdentityResult result = manager.Update(sub); // EXCEPTION here! Boom.
    if (!result.Succeeded)
    {
      Console.WriteLine("User did not save");
    }
  }
}

Q: What am I doing wrong here? Or, how should I attack this differently?

Shroombaker
  • 123
  • 1
  • 7
  • 4
    what does the manager.update do? – Dan Hunex Oct 03 '14 at 04:07
  • You might have a look at my answer on [ASP.NET MVC - Attaching an entity of type 'MODELNAME' failed because another entity of the same type already has the same primary key value](http://stackoverflow.com/questions/23201907/asp-net-mvc-attaching-an-entity-of-type-modelname-failed-because-another-ent/39557606#39557606). – Murat Yıldız Sep 18 '16 at 12:33

1 Answers1

1

Assuming manager is an instance of the ASP.NET Identity UserManager, the error is because Update() is trying to add the entity to the context when it was already added to the context when it was queried.

There are a couple ways to solve this. One is to update the user directly using EF (note that this bypasses any logic that would've been applied if saved via UserManager)...

foreach (var sub in subordinates)
{
    sub.Nickname = "Scooby"; // change an example test variable
}
_db.SaveChanges();

The other option is to use AsNoTracking() to prevent it from being added to the context during the query. After that, manager.Update(sub) should work...

List<ApplicationUser> subordinates = query.AsNoTracking()
                                       .Where(p => (p.ParentId == userEmployeeId))
                                       .ToList();
Anthony Chu
  • 37,170
  • 10
  • 81
  • 71
  • Thanks, Anthony. Using the manager.Update() is using a different context (behind the scenes) than the _db. So, calling manager.Update() wasn't what I needed -- it was _db.SaveChanges(); – Shroombaker Oct 04 '14 at 15:51