协调两个对象集合

时间:2009-10-29 16:23:13

标签: c# collections

我有一个表单,用户可以使用DataGrid修改对象集合。打开表单后,我创建了原始集合的深层副本,如果按下“取消”按钮,我只是丢弃该副本。

问题是当按下确定按钮时,我必须协调可能的更改:

  • 现有对象的已修改属性
  • 新对象已添加到集合中的任何位置。
  • 删除现有对象。
  • 现有物品已重新订购。

由于我需要保留原始引用,因此我不能只清除集合并添加修改后的项目。

你知道一个简单的算法来同步这样的两个集合吗?

我正在使用C#3.5,因此可以使用LINQ。

3 个答案:

答案 0 :(得分:1)

为什么不保留原件的副本,并绑定到实际的集合。如果绑定到实际集合,则表示没有对帐。按下取消时,只需将原始副本替换为原始副本即可。它基本上是你想要做的事情的倒置......但它应该更容易管理。

答案 1 :(得分:1)

我处理这个问题的方式取决于具有唯一ID的对象集合。我也通过存储库处理这个问题,但为了简洁起见,我把它排除在外。它类似于以下内容:

public static void MergeFields(IEnumerable<TYPE1> persistedValues, IEnumerable<TYPE1> newValues)
{
    var leftIds = persistedValues.Select(x => x.Id).ToArray();
    var rightIds = newValues.Select(x => x.Id).ToArray();

    var toUpdate = rightIds.Intersect(leftIds).ToArray();
    var toAdd = rightIds.Except(leftIds).ToArray();
    var toDelete = leftIds.Except(rightIds).ToArray();

    foreach(var id in toUpdate){
        var leftScope = persistedValues.Single(x => x.ID == id);
        var rightScope = newValues.Single(x => x.ID == id);

        // Map appropriate values from rightScope over to leftScope
    }

    foreach(var id in toAdd) {
        var rightScope = newValues.Single(x => x.ID == id);
        // Add rightScope to the repository
    }

    foreach(var id in toDelete) {
        var leftScope = persistedValues.Single(x => x.ID == id);
        // Remove leftScope from the repository
    }

    // persist the repository
}

答案 2 :(得分:0)

我刚刚为我正在进行的项目制定了以下算法,我认为它符合您的要求。它遵循以下步骤:

  1. 创建原始列表的浅表副本。
  2. 清除原始列表。
  3. 修改后的列表中的Foreach项目。
    1. 如果发现原始对象将其添加到列表中并更新其属性。
    2. 如果不只是将其添加到列表中。
  4. 此方法维护新订单并重用原始引用,但要求您的对象具有唯一标识符。我正在使用Guid。

    var originalPersons = m_originalList.ToList();
    m_originalList.Clear();
    foreach (var modifiedPerson in m_modifiedList)
    {
        var originalPerson = originalPersons.FirstOrDefault(c => c.ID == modifiedPerson.ID);
        if (originalPerson == null)
            m_originalList.Add(modifiedPerson);
        else
        {
            m_originalList.Add(originalPerson);
            originalPerson.Document = modifiedPerson.Document;
            originalPerson.Name = modifiedPerson.Name;
            ...
        }
    }
    
    祝你好运。