public async Task UpdateEntity <T>(T entity) where T : class, IEntity { using (var db = new Dota2HeroStatsDB()) { //db.Set<T>().Add(entity); db.Set <T>().Attach(entity); foreach (DbEntityEntry <IEntity> entry in db.ChangeTracker.Entries <IEntity>()) { IEntity currEntity = entry.Entity; entry.State = GetEntityState(currEntity.EntityState); } try { await db.SaveChangesAsync(); } catch (DbUpdateException e) { throw new DataSourceException("Error Updating item in database.", e); } } }
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)); }