c# - Entity Framework Many-to-Many Inserting Fine, But Not Properly Updating -
good morning!
i have many-to-many relationship between employee , skill entities. when create new employee, skills select added database without problem. however, when update employee, employee content updates, none of skills added/removed. see being passed repository, not updating database.
i have following many-to-many relationship:
public class employee : baseentity { public string firstname { get; set; } public string lastname { get; set; } public string jobtitle { get; set; } public virtual icollection<skill> skills { get; set; } }
and:
public class skill : baseentity { public string name { get; set; } public virtual icollection<employee> employees { get; set; } }
my controller adds/removes employee's skills through following method:
public actionresult edit(int id, employeeeditviewmodel viewmodel) { try { if (!modelstate.isvalid) { viewmodel.skillslist = _skillservice.getall().tolist(); return view(viewmodel); } var employee = mapper.map<employee>(viewmodel); updateskills(employee, viewmodel.newskills); _employeeservice.update(employee); return redirecttoaction("index"); } catch(exception e) { modelstate.addmodelerror("", e.message); viewmodel.skillslist = _skillservice.getall().tolist(); return view(viewmodel); } } private void updateskills(employee employee, ienumerable<int> updatedskills) { if (employee.skills != null) { var updatedskillslist = updatedskills ilist<int> ?? updatedskills.tolist(); var addedskills = updatedskillslist.except(employee.skills.select(x => x.id)); var removedskills = employee.skills.select(x => x.id).except(updatedskillslist); addedskills.foreach(x => employee.skills.add(_skillservice.getbyid(x))); removedskills.foreach(x => employee.skills.remove(_skillservice.getbyid(x))); } else { employee.skills = new list<skill>(); newskills.foreach(x => employee.skills.add(_skillservice.getbyid(x))); } }
the employee inserted/updated generic repository:
public void insert(tentity entity) { if (entity == null) throw new argumentnullexception("entity"); try { _dbset.add(entity); _dbcontext.savechanges(); } catch (dbentityvalidationexception ex) { throwvalidationerror(ex); } } public void update(tentity entity) { if (entity == null) throw new argumentnullexception("entity"); try { _dbset.attach(entity); _dbcontext.entry(entity).state = entitystate.modified; _dbcontext.savechanges(); } catch (dbentityvalidationexception ex) { throwvalidationerror(ex); } }
here how employee object being called data context.
my constructor:
protected readonly ntierapplicationsdatacontext _dbcontext; protected readonly dbset<tentity> _dbset; public efrepository(ntierapplicationsdatacontext dbcontext) { _dbcontext = dbcontext; _dbset = _dbcontext.set<tentity>(); }
here find method object:
public tentity getbyid(int id) { return _dbset.find(id); }
i think must update employee self after editing skills below
private void updateskills(employee employee, ienumerable<int> updatedskills) { if (employee.skills != null) { var updatedskillslist = updatedskills ilist<int> ?? updatedskills.tolist(); var addedskills = updatedskillslist.except(employee.skills.select(x => x.id)); var removedskills = employee.skills.select(x => x.id).except(updatedskillslist); addedskills.foreach(x => employee.skills.add(_skillservice.getbyid(x))); removedskills.foreach(x => employee.skills.remove(_skillservice.getbyid(x))); // here _employeeservice.update(employee); } else { employee.skills = new list<skill>(); newskills.foreach(x => employee.skills.add(_skillservice.getbyid(x))); } }
edit: check mapping
edit:
i think mapping entities has problem, can approach
public actionresult edit(int id, employeeeditviewmodel viewmodel) { try { if (!modelstate.isvalid) { viewmodel.skillslist = _skillservice.getall().tolist(); return view(viewmodel); } //here mapper not attaching employee context //var employee = mapper.map<employee>(viewmodel); can var employee = _employeeservice.getbyid(viewmodel.id); // after ... update user did view model except id id won't change employee = mapper.map<employee>(viewmodel, employee); // think mapping have overload map destination. can set setup mappnig in startup ignore updating ids updateskills(viewmodel.newskills); _employeeservice.update(employee); return redirecttoaction("index"); } catch(exception e) { modelstate.addmodelerror("", e.message); viewmodel.skillslist = _skillservice.getall().tolist(); return view(viewmodel); }
}
Comments
Post a Comment