時々、私はただ気が気になる...
私は簡単なクラスを持っています:
public class myClass
{
public long Id { get; set; }
public long ParentChannelId { get; set; }
}
私はクラスを含むリストを持っています:
List myItems = new List
さらにコードの下で、私はクラスでリストをフィードします。
今、私はリストから項目を削除したい。 しかし、アイテムは子供や孫などを持つことができるので... 私はすべての関連を削除したい..
次のようなことを考えていた: (擬似コード)
var List itemsToDelete = myItems.Where(i => i.Ancestors.Contains(myItemId));
しかし、私は本当にそれを正確に書く方法を知るために頭脳atmを持っていない:... \
私は .Ancestors
関数を持っています...
ちょうどlambda linqの助けが必要
public List Ancestors
{
get
{
List result = new List();
Channel channel = this;
while (channel != null)
{
result.Add(channel);
channel = myChannels.Where(c => c.ParentChannelId == this.Id).First();
}
result.Reverse();
return result;
}
}
EDIT: guess i did not explain myself as i should... i have all the properties like ancestors, children parent etc... i want to select all the classes that might contain the specific class...
私はあなたの質問、特に .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が階層クエリに変換できるかどうかは不明です。
これは、私がハッシュセットとRemoveAllメソッドを使って行う方法です。
var itemsToDelete = new HashSet(otherItems);
myItems.RemoveAll(i => itemsToDelete.Contains(i));
RemoveAll Method
http://msdn.microsoft.com/en-us/library/wdka673a.aspx