我有一个表单,用户可以使用DataGrid修改对象集合。打开表单后,我创建了原始集合的深层副本,如果按下“取消”按钮,我只是丢弃该副本。
问题是当按下确定按钮时,我必须协调可能的更改:
由于我需要保留原始引用,因此我不能只清除集合并添加修改后的项目。
你知道一个简单的算法来同步这样的两个集合吗?
我正在使用C#3.5,因此可以使用LINQ。
答案 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)
我刚刚为我正在进行的项目制定了以下算法,我认为它符合您的要求。它遵循以下步骤:
此方法维护新订单并重用原始引用,但要求您的对象具有唯一标识符。我正在使用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;
...
}
}
祝你好运。