当我更改它的副本时,为什么我的原始哈希集发生了变化?如何避免它?

时间:2014-10-03 09:33:45

标签: c# hashset

以下代码的目的是更新我的数据库中的内容以匹配用户在我的前端选择的内容。适当的Guid位于Session变量中,_alreadyLinkedContacts包含已存在于数据库中的用户。

    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";
    }

过滤contactsToAdd后,contactsInSession也已更改,不包括与系统中相同的guid。因此,它不会从contactsToRemove中删除任何内容,并且删除了我数据库中已有的任何内容,而不仅仅是会话中没有的内容。

为什么会发生这种情况,我该如何避免呢?

2 个答案:

答案 0 :(得分:3)

正如您在执行以下操作时的评论中所说:

HashSet<Guid> contactsToAdd = contactsInSession;

您正在指定第二个变量以引用与原始变量相同的HashSet。如果您执行以下操作,您将创建一个新的HashSet,它是原始文件的副本。

HashSet<Guid> contactsToAdd = new HashSet<Guid>(contactsInSession);

您可能希望对要获得HashSet副本的所有作业执行相同的操作。

答案 1 :(得分:1)

您正在将contactsToRemove和contactsInSession指向同一个HashSet。为什么你不期望contactsToRemove.RemoveWhere()影响contactsInSession HashSet?我认为您缺少将数据从一个哈希集复制到另一个哈希集的步骤,在您的代码中,您始终复制引用而不是哈希集的内容。

几乎可以肯定这两行

    //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;

不正确;他们应该复制源hashset中的数据,而不是将引用指针复制到该hashset。通过执行引用复制,您只需声明两个指向同一哈希集的变量 - 通过contactsToAdd或contactsInSession进行的任何更改都将影响相同的哈希集。