2013-07-03 54 views
0

所以,我有一个树形视图,其中一些行来自DataTable。当我取的数据表,我想用下面的基本规则,以更新树:存在于树,但没有相应的行 DataTable中 查找两个数据表之间的差异

  • 更新节点中存在的

    • 删除节点但需要更新 (不同日期时间)
    • 插入 树中不存在但在DataTable中执行的节点。

    为此我有一个字典,散列一个GUID(在数据表的主键),以树节点:

    Dictionary<Guid, NoteNode> MyHashNoteToNode; 
    

    ,其中NoteNode从树节点衍生的,通过添加一个LastEdit的日期时间字段。到目前为止,如此平庸。

    为了找到代表树和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); 
        } 
    } 
    

    }

  • 回答

    1

    一个简单的方法,使你的字典从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]); 
    
    +0

    我喜欢这个。谢谢。 – Robinson