Linq - ajdodlaringiz bu erda qaysi joyni tanlang?

ba'zida, faqat ahmoqona his qilaman ...

Menda oddiy dars bor:

public class myClass
{
    public long Id { get; set; }
    public long ParentChannelId { get; set; }
}

va sinfni o'z ichiga olgan ro'yxat mavjud:

List myItems = new List

kodni yanada pastga tushirish, ro'yxatni sinflar bilan to'ldirish.

Endi men ro'yxatdagi ob'ektni o'chirib tashlamoqchiman. Lekin, bu narsa bolalar va nabiralar va boshqalar bo'lishi mumkin ... Men hamma narsani o'chirib tashlamoqchiman.

kabi bir narsa haqida o'ylardi: (pseudo kodi)

var List itemsToDelete = myItems.Where(i => i.Ancestors.Contains(myItemId));

Lekin men, albatta, qanday yozishni bilish uchun miyamga ega emasman ...: \ .dasturlari funktsiyasi mavjud ... faqat lambda linq bilan yordamga muhtojmiz

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
Sizning tarkibingizni o'chirib tashlamoqchisiz List itemsToDelete?
qo'shib qo'ydi muallif dknaack, manba
Ajdodlar mulk mavjud emas. Iltimos, ko'proq manba kodini bering.
qo'shib qo'ydi muallif dknaack, manba
@dknaack - yo'q, uni o'chirish uchun kanallar bilan to'ldirmoqchiman.
qo'shib qo'ydi muallif Dementic, manba
@BoltClock - Q ga qo'shilgan.
qo'shib qo'ydi muallif Dementic, manba
@ sq33G - mening pseucode bilan bog'liq muammo .Qanday narsaga ega bo'lish kerak?
qo'shib qo'ydi muallif Dementic, manba
@ sq33G: U buni yolg'on-kod deb aytdi, shuning uchun bunday narsaga ega emasligiga ishonishimga olib keldi. Men javob berishga shoshqaloqlikda, men "Mening ajdodlarim bor. O'zgartirilgan javobni ko'ring.
qo'shib qo'ydi muallif Merlyn Morgan-Graham, manba
Ajdarlar xususiyati uchun kod nima?
qo'shib qo'ydi muallif BoltClock, manba
Xullas, kuting ... Agar shunday qilishni xohlasangiz, itemsToDelete pseudocode bilan nima yomon?
qo'shib qo'ydi muallif sq33G, manba
... nima uchun kod hozirda haqiqiy lavozimda bo'lsa, ajdodlar yo'q? (shuning uchun pastga tushish)
qo'shib qo'ydi muallif sq33G, manba
Men endi LINQ va bularning hammasini yaxshi ko'radiganman, lekin men bu muammolarni echishning yagona yo'li deb hisoblamayman. Ko'proq optimallash yechim hashtani yoki ro'yxatni tuzish o'rniga, rentabellikni ishlatish, uni qaytarib olish va qaytarish, masalan, @Merlyn Morgan-Grahamning javobiga qarang.
qo'shib qo'ydi muallif edvaldig, manba

2 javoblar

Men sizning savolingizni qayta o'qib chiqdim, ayniqsa, oxirgi qismda sizda .dasturlari deganingiz va endi bu mantiqan to'g'ri keladi.

O'chirish uchun ma'lumotlar ro'yxatini olish uchun buni bajaring:

List itemsToDelete = myItems
    .Where(i => i.Id == myItemId)
    .SelectMany(i => i.Ancestors)
    .Concat(myItems)//Want to delete these too, not just the ancestors
    .ToList()
    ;

Keyin natija orqali foreach mumkin va ularni asl ro'yxatidan chiqaring.

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.

Tartibga solishdan oldin:

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.

Lekin bu erda siz o'zingiz erishmoqchi bo'lgan narsalarni qanday qilib bajarishingiz mumkin:

Agar siz Linq to Objects (Linq to SQL yoki Linq to Entities) dan foydalanayotgan bo'lsangiz, MyClass deb nomlangan xususiyatni o'rniga to'g'ri turdagi ularni Id bilan bog'lashga harakat qilmoqda.

Keyin Atalar xususiyati juda osonlik bilan amalga oshiring:

public IEnumerable Ancestors
{
    get
    {
        MyClass current = this;

        while(current != null)
        {
            current = current.Parent;
            yield return current;
        }
    }
}

Agar sinfni tahrir qila olmasangiz, GetAncestors deb nomlangan kengaytma usulini qiling.

So'ngra, savolingizda yozgan kodga juda o'xshash bir narsa foydalanishingiz mumkin:

List itemsToDelete = myItems
    .Where(i => i.Ancestors.Any(a => a.Id == myItemId))
    .ToList();

Tashkilotlarga Linq

Kontaktlarni Linq-dan foydalanayotgan bo'lsangiz, ota-onaga o'tish uchun MyClass turidagi navigatsiya xususiyatini yarating va xuddi shu narsani bajaring. Bu qayta so'rovlarga olib kelishi mumkinligini unutmang. Linqning ierarxik so'rovga tarjima qilishi mumkin yoki olmasligiga ishonchimiz komil emas.

2
qo'shib qo'ydi
Mening ajdodlarim, ota-onalarim va farzandlarim bor. Faqat ma'lum bir sinfni o'z ichiga olgan barcha sinflarni qanday tanlashni bilish kerak.
qo'shib qo'ydi muallif Dementic, manba
Men yozayotganimda meni urish uchun +1 :)
qo'shib qo'ydi muallif edvaldig, manba

Buni xashset va RemoveAll usuli yordamida amalga oshirishim mumkin.

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

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

1
qo'shib qo'ydi