Linq - выбраць, дзе продкі ўтрымліваюць гэта?

Часам, я проста адчуваю сябе тупы ...

У мяне ёсць просты клас:

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));

але я сапраўды не маюць мазгі атм, каб ведаць, як напісаць гэта дакладна ...: \ у мяне ёсць .Ancestors функцыі ... проста трэба дапамагчы з лямбда-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...

0
Вы хочаце, каб выдаліць змесціва вар List itemsToDelete?
дададзена аўтар dknaack, крыніца
Продкі ўласцівасць не існуе. Просьба даць больш зыходнага кода.
дададзена аўтар dknaack, крыніца
@dknaack - не, я хачу, каб запоўніць яго з каналамі для выдалення.
дададзена аўтар Dementic, крыніца
@BoltClock - дадаецца ў Q.
дададзена аўтар Dementic, крыніца
@ Sq33G - праблема з маім pseucode з'яўляецца .Contains трэба карміць пункт, у той час як я хачу, каб карміць яго ідэнтыфікатар элемента.
дададзена аўтар Dementic, крыніца
@ Sq33G: Яму кажуць, што гэта псеўда-код прыводзіць мяне да думкі, што не валодаюць такой уласцівасцю. У маім парыве, каб адказаць, што я прапусціў, калі ён сказаў: «У мяне ёсць функцыя .Ancestors». Глядзіце мой адрэдагаваны адказ.
дададзена аўтар Merlyn Morgan-Graham, крыніца
Што код для Продкаў нерухомасць?
дададзена аўтар BoltClock, крыніца
Так, пачакайце ... Калі гэта тое, што вы хочаце зрабіць, што было не так з вашым itemsToDelete псевдокодом?
дададзена аўтар sq33G, крыніца
... чаму вы кажаце, што няма ніякіх Продкаў, калі код (цяпер) прама на зыходнае паведамленне? (Адсюль downvote)
дададзена аўтар sq33G, крыніца
Цяпер я вялікі прыхільнік LINQ і ўсё гэта, але я не думаю, што варта лічыць адзіным спосабам вырашэння пералічоных праблем. Значна больш аптымальным рашэннем будзе выкарыстанне выхаду замест пабудовы некаторай HashSet або спісу, змяніўшы яго і вяртанне см адказу @Merlyn Морган-Грэм
дададзена аўтар edvaldig, крыніца

2 адказы

Я перачытаў сваё пытанне, асабліва ў апошняй частцы, дзе вы сказалі, у вас ужо ёсць .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()
    ;

Тады вы можаце Еогеасп праз вынік, і выдаліць іх з першапачатковага спісу.

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.

<Моцны> Перад Edit:

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 да аб'ектаў (у адрозненне ад Linq для SQL або Linq да Entities), зрабіць ўласцівасць Бацька на MyClass , правільнага тыпу, а спрабуючы звязаць іх з дапамогай Id .

Тады вы можаце зрабіць Продкі <код /> нерухомасць даволі лёгка:

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 да Entities

Калі вы выкарыстоўваеце Linq для асоб, стварыць ўласцівасць навігацыі тыпу MyClass , каб перайсці да бацькі, і рабіць тое ж самае. Звярніце ўвагу, што гэта можа прывесці да паўторных запытам. Не ўпэўнены, што Linq можа ці ж перакладаюцца ў іерархічны запыт.

2
дададзена
У мяне ёсць продкі і бацькі і дзеці. Мне проста трэба ведаць, як выбраць усе класы, якія ўтрымліваюць пэўны клас.
дададзена аўтар Dementic, крыніца
+1 за зьбіцьцё мяне да яго, пакуль я друкаваў :)
дададзена аўтар edvaldig, крыніца

Гэта, як я хацеў бы зрабіць гэта з дапамогай HashSet і метад RemoveAll.

var itemsToDelete = new HashSet(otherItems);
myItems.RemoveAll(i => itemsToDelete.Contains(i));

RemoveAll Method
http://msdn.microsoft.com/en-us/library/wdka673a.aspx

1
дададзена