Reconciling two collections of objects

后端 未结 3 695
后悔当初
后悔当初 2021-01-15 19:16

I have a form where users can modify a collection of objects using a DataGrid. When the form is opened I create a deep copy of the original collection and if the Cancel butt

相关标签:
3条回答
  • 2021-01-15 19:33

    Why not keep a copy of the original, and bind to the actual collection. If you bind to the actual collection, then there is no reconciliation. When cancel is pressed, simply replace the actual collection with the copy of the original. It is basically an inversion of what you are trying to do...but it should be a lot easier to manage.

    0 讨论(0)
  • 2021-01-15 19:41

    I just worked out the following algorithm for a project I'm working on and I think it complies with your requirements. It follows this steps:

    1. Creates a shallow copy of the original list.
    2. Clears the original list.
    3. Foreach item in the modified list.
      1. If it finds the original object adds it to the list and updates it's properties.
      2. If not just add it to the list.

    This method maintains the new order and reuses the original references but requires that your objects have an unique identifier. I'm using a Guid for that.

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

    Good luck.

    0 讨论(0)
  • 2021-01-15 19:51

    The way I've dealt with this depends on the collections of objects having a unique ID. I also pass in the repository to deal with this as well, but for brevity I left it out. It's similiar to the following:

    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
    }
    
    0 讨论(0)
提交回复
热议问题