Reputation: 3555
The intent of the below code is that it updates what's in my database to match what the user selected in my frontend. The proper Guids are in the Session variable, and _alreadyLinkedContacts
contains the users that are already in the database.
protected void btnAssignContacts_OnClick(object sender, EventArgs e)
{
btnAssignContacts.Enabled = false;
//Venn diagram:
//(Only in session --> add(both in session and Database -> keep) Only in database --> remove )
HashSet<Guid> contactsInSession = (HashSet<Guid>)Session[SelectedContactsSessionVar];
HashSet<Guid> contactsInDatabase = _alreadyLinkedContacts;
//Everything that's in the session should go in the database;
HashSet<Guid> contactsToAdd = contactsInSession;
//Base the set to remove on that in the database.
HashSet<Guid> contactsToRemove = contactsInDatabase;
// We don't need to add those that are in the database already;
contactsToAdd.RemoveWhere(contactsInDatabase.Contains);
MarketingDirector.AddContactsToMarketingList(contactsToAdd.ToList(), _marketinglist.Id);
// Those that are currently in the session don't need to be removed from the database, all the others do.
contactsToRemove.RemoveWhere(contactsInSession.Contains);
MarketingDirector.RemoveContactsFromMarketingList(contactsToRemove.ToList(), _marketinglist.Id);
btnAssignContacts.Text = "Contacts assigned";
}
After contactsToAdd
has been filtered, contactsInSession
has been changed as well, excluding the same guids as are in my system. Because of this, it doesn't remove anything from contactsToRemove
and anything that already was in my database is removed, instead of just the stuff that is not in the session.
Why does this happen and how can I avoid it?
Upvotes: 0
Views: 734
Reputation: 6222
You are making contactsToRemove and contactsInSession point to the same HashSet. Why wouldn't you expect contactsToRemove.RemoveWhere() to affect the contactsInSession HashSet ? I think you are missing a step which copies the data from one hashset to another, in your code you are always copying the reference not the content of the hashset.
Almost certainly these two lines
//Everything that's in the session should go in the database;
HashSet<Guid> contactsToAdd = contactsInSession;
//Base the set to remove on that in the database.
HashSet<Guid> contactsToRemove = contactsInDatabase;
Are incorrect ; they should copy the data from the source hashset not copy the reference pointer to that hashset. By doing reference copying you are simply declaring two variables which point to the same hashset - any changes made via either contactsToAdd OR contactsInSession will affect the same hashset.
Upvotes: 1
Reputation: 21881
As you seem to say in your comments when you do the following:
HashSet<Guid> contactsToAdd = contactsInSession;
You are assigning a second variable to reference the same HashSet
as the original. If you do the folowing you will create a new HashSet
that is a copy of the original.
HashSet<Guid> contactsToAdd = new HashSet<Guid>(contactsInSession);
You might want to do the same for all your assignments where you want a copy of the HashSet.
Upvotes: 3