1

所以,我有一个树视图,其中一些行来自 DataTable。当我获取数据表时,我想使用以下基本规则更新树:

  • 删除树中存在但在 DataTable 中没有对应行的节点
  • 更新树中存在但需要更新的节点(不同的 DateTime)
  • 插入树中不存在但在 DataTable 中存在的节点。

为此,我有一个字典,将 Guid(DataTable 中的主键)散列到树节点:

Dictionary<Guid, NoteNode> MyHashNoteToNode;

,其中 NoteNode 派生自 TreeNode,并添加了 LastEdit DateTime 字段。到目前为止,如此平庸。

为了找到代表树和 DataTable 之间差异的 3 个集合,我编写了下面的代码。我很想听到有一个非常简单的 Linq 查询可以返回 3 个集合(插入、编辑、删除),或者可以为我做的简洁的东西,也许是我在某处遗漏的方法。或者这几乎是最优的?

// Find all items that need inserting.
List<DataRow> toInsert = new List<DataRow>();
foreach (DataRow row in MyNotes.Rows)
{
    NoteNode node = null;
    MyHashNoteToNode.TryGetValue((Guid)row["ID"], out node);
    if(node == null)
    {
        toInsert.Add(row);
    }
}

// Find all items that need editing/changing.
List<DataRow> toEdit = new List<DataRow>();
foreach (DataRow row in MyNotes.Rows)
{
    NoteNode node = null;
    MyHashNoteToNode.TryGetValue((Guid)row["ID"], out node);
    if(node != null)
    {                
        if((DateTime)row["Edited"] != node.LastEdit)
        {
            toEdit.Add(row);
        }
    }
}

// Find all items that need deleting.
List<NoteNode> toDelete = new List<NoteNode>();
foreach (NoteNode node in MyHashNoteToNode.Values)
{
    if (!MyNotes.Rows.Contains(node.Key))
    {
        toDelete.Add(node);
    }
}

}

4

1 回答 1

1

从 a 制作字典的一种简单方法DataTable是,

DataSet newData;
DataSet existingData;

var before = existingData.AsEnumerable().ToDictionary(
    n => Guid.Parse(n.Field<string>("ID")),
    n => n);

var after = newData.AsEnumerable().ToDictionary(
    n => Guid.Parse(n.Field<string>("ID")),
    n => n);

要找到需要工作的密钥,

var keysToInsert = after.Select(p => p.Key).Except(before.Select(p => p.Key));
var keysToDelete = before.Select(p => p.Key).Except(after.Select(p => p.Key));
var keysTheSame = before.Select(p => p.Key).Intersect(after.Select(p => p.Key));

要找到需要工作的行,

var nodesToInsert = keysToInsert.Select(k => after[k]);

var nodesToDelete = keysToDelete.Select(k => before[k]);

var nodesThatNeedUpdates = keysTheSame
    .Where(k => 
        before[k].Field<DateTime>("Edited") !=
        after[k].Field<DateTime>("Edited"))
    .Select(k => after[k]);
于 2013-07-03T11:00:28.883 回答