public async Task <IHttpActionResult> PutAbility(int id, AbilityDataTransferObject ability) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (id != ability.AbilityId) { return(BadRequest()); } var dataSourceAbility = await db.Abilities.Include(a => a.OriginalAbilityOwner).FirstOrDefaultAsync(a => a.AbilityId == id); if (dataSourceAbility == null) { return(NotFound()); } var attachedEntry = db.Entry(dataSourceAbility); attachedEntry.CurrentValues.SetValues(ability); //copy values from dto to data source object. if (ability.OriginalAbilityOwnerId == null || ability.OriginalAbilityOwnerId == 0) {//if passed in ability has no originalhero set. dataSourceAbility.OriginalAbilityOwner = null; } else { //there was a passed in originalabilityowner //check if the id of passed in ability is the same as one already in db var needToUpdate = dataSourceAbility.OriginalAbilityOwner == null ? true : dataSourceAbility.OriginalAbilityOwner.HeroId == ability.OriginalAbilityOwnerId; var dataSourcePassedInAbilityOriginalHero = await db.Heroes.FirstOrDefaultAsync(h => h.HeroId == ability.OriginalAbilityOwnerId); if (dataSourcePassedInAbilityOriginalHero != null) { dataSourceAbility.OriginalAbilityOwner = dataSourcePassedInAbilityOriginalHero; } else { return(BadRequest("An original ability owner with that ID could not be found.")); } } db.Entry(dataSourceAbility).State = EntityState.Modified; try { await db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!AbilityExists(id)) { return(NotFound()); } else { throw; } } return(StatusCode(HttpStatusCode.NoContent)); }
public async Task <IHttpActionResult> PutHero(int id, HeroDataTransferObject hero) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (id != hero.HeroId) { return(BadRequest()); } var dataSourceHero = await db.Heroes.Include(h => h.Roles).FirstOrDefaultAsync(h => h.HeroId == id); if (dataSourceHero == null) { return(NotFound()); } //using attach stuff from https://blog.maskalik.com/entity-framework/2013/12/23/entity-framework-updating-database-from-detached-objects/ //entity is already in the context var attachedEntry = db.Entry(dataSourceHero); attachedEntry.CurrentValues.SetValues(hero); //copy values from dto to data source object. var roleConverter = new RoleStringToModelConverter(ServiceLocator.GetInstance().GetService <IDataSource>()); var roleModelSet = await roleConverter.CreateRoleList(hero.Roles); //create role models from string list in dto. //get roles to add var rolesToAdd = GetRolesToAdd(dataSourceHero, roleModelSet); //get roles to remove var rolesToRemove = GetRolesToRemove(dataSourceHero, roleModelSet); //remove the roles we don't want foreach (Role curr in rolesToRemove) { dataSourceHero.Roles.Remove(curr); } //add the roles to the datasourceHero that are new. foreach (Role curr in rolesToAdd) { if (curr.EntityState == ModelEntityState.Unchanged) { var dbRole = await db.Set <Role>().FindAsync(curr.RoleId); dataSourceHero.Roles.Add(dbRole); } else { dataSourceHero.Roles.Add(curr); } } try { await db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!HeroExists(id)) { return(NotFound()); } else { throw; } } return(StatusCode(HttpStatusCode.NoContent)); }