私はあなたの質問、特に .Ancestors
を持っていると言った最後の部分をもう一度読んだので、もっと意味があります。
削除するアイテムのリストを取得するには、これを行います:
List itemsToDelete = myItems
.Where(i => i.Id == myItemId)
.SelectMany(i => i.Ancestors)
.Concat(myItems)//Want to delete these too, not just the ancestors
.ToList()
;
次に結果を foreach
して元のリストから削除します。
I'd suggest keeping these in a Dictionary
or a HashSet
instead of a list, since removal will be way faster.
For a HashSet
, you'll have to implement Equals
and GetHashCode
, or create an IEqualityComparer
implementation to provide those methods.
編集前:
I wouldn't write my code this way. I'd simply create a Dictionary
instead of a list. It will do a lookup way faster than anything involving ancestors/tree traversal.
しかし、達成しようとしていることを達成する方法はここにあります:
Linq to ObjectsまたはLinq to Entitiesとは対照的に、Linq to Objectsを使用している場合は、正しいタイプの MyClass
に Parent
というプロパティを Id
でそれらをリンクしようとしています。
それで、 Ancestors
プロパティをかなり簡単に作ることができます:
public IEnumerable Ancestors
{
get
{
MyClass current = this;
while(current != null)
{
current = current.Parent;
yield return current;
}
}
}
クラスを編集できない場合は、 GetAncestors
という拡張メソッドを作成します。
次に、あなたの質問に書いたコードに非常によく似た何かを使うことができます:
List itemsToDelete = myItems
.Where(i => i.Ancestors.Any(a => a.Id == myItemId))
.ToList();
エンティティへのLinq
Linq to Entitiesを使用している場合は、 MyClass
型のナビゲーションプロパティを作成して親に移動し、同じことをします。これにより、再クエリが発生する可能性があることに注意してください。 Linqが階層クエリに変換できるかどうかは不明です。