Home > Software design >  ASP.NET Core MVC : remove many-to-many entries before posting Edit method
ASP.NET Core MVC : remove many-to-many entries before posting Edit method

Time:12-11

I have a many-to-many relationship between Project and Member realized with join table ProjectMembers. On view in order to add particular project members I use multiple select which stores MemberId in IEnumerable<int> SelectedMembers.

Everything works correctly except I can only update (Edit) Project with new members (members which are not selected and were part of database before remain untouched). I need help with removing the existing members in ProjectMember which are connected to the specific ProjectId before posting the updated set of members. I have tried a lot but nothing worked so far. Really any advice would be appreciated.

This is my Edit post method in ProjectController:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(int? id, CreateProjectViewModel viewmodel)
{
    Project project = _context.Project
                              .Single(m => m.ProjectId == id);
            
    project.Name = viewmodel.Name;
    project.Budget = viewmodel.Budget;
    project.BusinessCase = viewmodel.BusinessCase;
    project.StartDate = viewmodel.StartDate;
    project.FinishDate = viewmodel.FinishDate;
    project.ClientId = viewmodel.ClientId;

    // here I need the method to remove the existing instances of Member in ProjectMember

    // part of code below is validation that there will be no conflict of PrimaryKeys on ProjectMember, probably can be removed once the Remove method is implemented
    foreach (var selectedId in viewmodel.SelectedMembers)
    { 
        var projectID = project.ProjectId;
        var memberID = selectedId;
             
        IList<ProjectMember> existingItems = _context.ProjectMembers
                .Where(cm => cm.MemberId == memberID)
                .Where(cm => cm.ProjectId == projectID).ToList(); 
                
        if (existingItems.Count == 0)
        {
            _context.ProjectMembers.Add(new ProjectMember
                    {
                        ProjectId = project.ProjectId,
                        MemberId = selectedId,
                    });
        } 
    }

    _context.SaveChanges();

    return RedirectToAction("Index");
}

UPDATE: Based on similar threads I came up with following to be added before the new rows are being added into ProjectMembers with the POST Edit:

        var project = _context.Project.Include(a => a.ProjectMembers)
    .SingleOrDefault(m => m.ProjectId == id);

    if (project != null)
        {
            foreach (var projectMember in project.ProjectMembers
                .Where(at => viewmodel.SelectedMembers.Contains(at.MemberId)).ToList())
            {
                project.ProjectMembers.Remove(projectMember);
            }
            _context.SaveChanges();
        }

Unfortunately the entries which should be deleted in ProjectMembers keep on staying, Can anyone advice what should be changed?

CodePudding user response:

Got it. Apparently a much easier way to do it. Code below is to remove the entires before new ones can be passed:

   var project = _context.Project.Include(a => a.ProjectMembers)
.SingleOrDefault(m => m.ProjectId == id);

    foreach (var member in project.ProjectMembers.ToArray())
    {
        project.ProjectMembers.Remove(member);
    }
  • Related