ListBox Update Handling I have UserGroups for Users to be assigned to in a ListBox in HTML form. Items from listbox can be multi-selected or completely unselected.

In summary currently, I am getting a int[] of GroupId from client into my action and I am pulling existing assigned usergroups for the user into the action as well. Then I am comparing the Length of both int[] to determine whether UserGroups for the User was added or removed which is depicted in the following flow chart:



Actual code:

var existUserGroups = db.Users.Where(u =&gt; u.ID == user.ID).Single().UserGroups;
var existUserGroupsIds = db.Users.Where(u =&gt; u.ID == user.ID).Single().UserGroups.Select(ug =&gt; ug.ID).ToArray&lt;int&gt;();
var newUserGroupsIds = user.GroupId ?? new int[0];

//No change made
if (!existUserGroupsIds.SequenceEqual(newUserGroupsIds))
{
    //Add
    if (newUserGroupsIds.Length &gt; existUserGroupsIds.Length)
    {
        for (int i = 0; i &lt; newUserGroupsIds.Length; i++)
        {
            if (!existUserGroupsIds.Any(id =&gt; id == newUserGroupsIds[i]))
            {
                int id = newUserGroupsIds[i];
                existUserGroups.Add(db.UserGroups.Where(ug =&gt; ug.ID == id).Single());
            }
        }
    }
    //Remove
    else if (newUserGroupsIds.Length &lt; existUserGroupsIds.Length)
    {
        var diff = existUserGroupsIds.Except(newUserGroupsIds);
        if (diff != null &amp;&amp; diff.Count() &gt; 0)
        {
            for (int i = 0; i &lt; diff.Count(); i++)
            {
                int id = diff.ElementAt(i);
                existUserGroups.Remove(db.UserGroups.Where(ug =&gt; ug.ID == id).Single());
            }
        }
    }
    //Update
    else
    {
        existUserGroups.Remove(existUserGroups.ElementAt(0));
        int id = newUserGroupsIds[0];
        existUserGroups.Add(db.UserGroups.Where(ug =&gt; ug.ID == id).Single());
    }

    db.SaveChanges();
}


This is working but the code seems to be very tangled. So, please suggest how I can improve this code or how devs usually handle such situations.
Small Code duplication

var existUserGroups = db.Users.Where(u =&gt; u.ID == user.ID).Single().UserGroups;
var existUserGroupsIds = db.Users.Where(u =&gt; u.ID == user.ID).Single().UserGroups.Select(ug =&gt; ug.ID).ToArray&lt;int&gt;();


can be reduced to

var existUserGroups = db.Users.Where(u =&gt; u.ID == user.ID).Single().UserGroups;
var existUserGroupsIds = existUserGroups.Select(ug =&gt; ug.ID).ToArray&lt;int&gt;();


The //Add part

Should be simplified using a foreach loop and made more readable by using the Contains() method

foreach (int newId in newUserGroupsIds)
{
    if (!existUserGroupsIds.Contains(newId))
    {
        existUserGroups.Add(db.UserGroups.Where(ug =&gt; ug.ID == newId).Single());
    }
}


The //Remove part

var diff = existUserGroupsIds.Except(newUserGroupsIds);


diff will never be null => the null check can be skipped
using a for..each instead of a for loop => the check for diff.Count() &gt; 0 can be skipped

var diff = existUserGroupsIds.Except(newUserGroupsIds);
foreach (int id in diff)
{
    existUserGroups.Remove(db.UserGroups.Where(ug =&gt; ug.ID == id).Single());
}