1

したがって、ツリー ビューがあり、その一部の行は DataTable から取得されます。データ テーブルをフェッチするときに、次の基本的なルールでツリーを更新したいと考えています。

  • ツリーに存在するが DataTable に対応する行がないノードを削除する
  • ツリーに存在するが更新が必要な更新ノード (異なる DateTime)
  • ツリーには存在しないが DataTable には存在するノードを挿入します。

そのために、Guid (DataTable の主キー) をツリー ノードにハッシュする辞書があります。

Dictionary<Guid, NoteNode> MyHashNoteToNode;

ここで、NoteNode は TreeNode から派生し、LastEdit DateTime フィールドが追加されています。これまでのところ、とても平凡です。

ツリーと DataTable の違いを表す 3 つのセットを見つけるために、以下のコードを書きました。3 つのセット (挿入、編集、削除) を返す非常に単純な Linq クエリ、またはそれを実行する簡潔なクエリがあることを知りたいです。おそらく、どこかに欠けているメソッドです。それとも、これはかなり最適ですか?

// 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

から辞書を作成する簡単な方法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 に答える