2009-06-22 12 views
28

निम्नलिखित वर्गों के बाद (अत्यधिक सरलीकृत):LINQ: किसी भी सूची में आइटम को एक सूची में कैसे प्राप्त करें?

public class Child 
{ 
    public string Label; 
    public int CategoryNumber; 
    public int StorageId; 
} 

public class Parent 
{ 
    public string Label; 
    public List<Child> Children = new List<Child>(); 
} 

और निम्न डेटा होने: अब

var parents = new List<Parent>(); 

var parent = new Parent() {Label="P1"}; 
parent.Children.Add(new Child() {Label="C1", CategoryNumber=1, StorageId=10}); 
parent.Children.Add(new Child() {Label="C2", CategoryNumber=2, StorageId=20}); 
parents.Add(parent); 

parent = new Parent() {Label="P2"}; 
parent.Children.Add(new Child() {Label="C3", CategoryNumber=1, StorageId=10}); 
parent.Children.Add(new Child() {Label="C4", CategoryNumber=2, StorageId=30}); 
parents.Add(parent); 

parent = new Parent() {Label="P3"}; 
parent.Children.Add(new Child() {Label="C5", CategoryNumber=3, StorageId=10}); 
parent.Children.Add(new Child() {Label="C6", CategoryNumber=2, StorageId=40}); 
parents.Add(parent); 

, मैं कैसे बच्चों की एक सूची प्राप्त होगा (साथ CategoryNumber = 2) सूची से माता-पिता में से कम से कम एक बच्चा श्रेणी संख्या = 1 वाला है?

मैं निम्न कर सकते हैं, लेकिन यह इष्टतम होना प्रतीत नहीं होता है:

var validParents = from p in parents 
        where p.Children.Any (c => c.CategoryNumber==1) 
        select p; 
var selectedChildren = validParents.Select(p => from c in p.Children 
               where c.CategoryNumber == 2 
               select c); 

यहाँ मैं selectedChildren के लिए क्या मिलता है:

  • IEnumerable<IEnumerable<Child>>
    • IEnumerable<Child>
      • सी 2 2 20
    • IEnumerable<Child>
      • सी 4 2 30

क्या यह संभव है करने के लिए केवल एक ही फ्लैट दो बच्चों दो उप-सूची के बजाय तत्वों से युक्त सूची है? LINQ में इसका अनुवाद कैसे किया जाएगा?

उत्तर

33

Scott का जवाब बहुत अच्छा है; मैं तो बस का कहना है कि आप वास्तव में इस प्रश्न के क्वेरी निरंतरता वाक्य रचना उपयोग कर सकते हैं करना चाहते हैं:

from parent in parents 
where parent.Children.Any (c => c.CategoryNumber==1) 
select parent into p 
from child in p.Children 
where child.CategoryNumber == 2 
select child 

सूचना कैसे आप पाइप की सुविधा देता है "में" अगले क्वेरी में एक क्वेरी के परिणाम । बहुत चालाक, आह?

+1

@Eric: हाँ, इसके लिए LINQ क्वेरी सिंटैक्स काफी अच्छा है (और शायद मिश्रण क्वेरी और एक्सटेंशन विधि वाक्यविन्यास के विपरीत उपयोग करने के लिए थोड़ा बेहतर है)। जब भी मुझे इस विषय का सामना करना पड़ता है, मुझे लगता है कि LINQ में एक कॉन्सटेनेशन ऑपरेटर (F # में Seq.concat के समान) गायब है, जिसे SelectMany के विकल्प के रूप में उपयोग किया जा सकता है, और वास्तव में अन्य मामलों में बहुत आसान है। Enumerable.Concat विधि का एक सरल अधिभार जो IENumerable > पैरामीटर लेता है, वह काम बहुत अच्छी तरह से करेगा। इसके बारे में कोई विचार (या इससे भी बेहतर, योजनाएं)?http://code.google.com/p/morelinq/wiki/OperatorsOverview: – Noldorin

+0

आह, यह MoreLINQ इस ऑपरेटर को परिभाषित करता है लगता है। हालांकि बीसीएल में होना बहुत अच्छा होगा (ज़िप जैसे कुछ अन्य लोगों के साथ)। – Noldorin

+0

धन्यवाद ... आप मेरा दिन बचाओ – thiagolsilva

41

SelectMany और Where का उपयोग करके आप एक साथ दो प्रश्नों को स्ट्रिंग कर सकते हैं।

var selectedChildren = (from p in parents 
         where p.Children.Any (c => c.CategoryNumber==1) 
         select p) 
         .SelectMany(p => p.Children) 
         .Where(c => c.CategoryNumber == 2); 

// or... 

var selectedChildren = parents 
         .Where(p => p.Children.Any(c => c.CategoryNumber == 1)) 
         .SelectMany(p => p.Children) 
         .Where(c => c.CategoryNumber == 2); 
+0

बढ़िया काम करता है! SelectMany एक उपयोगी विधि प्रतीत होता है। क्या आपके पास लिंक के बारे में पूरी तरह से समझने के बारे में कोई वेबसाइट या पुस्तक के लिए कोई सुझाव है? –

+0

साइट्स के लिए, जिस पर आप जा रहे हैं वह अच्छा है - मेरी अधिकांश linq समस्याओं को त्वरित खोज या यहां पोस्ट किए गए प्रश्न के साथ हल किया गया है। एकमात्र पुस्तक जिसे मैंने देखा है वह है ... http://www.amazon.com/Programming-Microsoft%C2%AE-PRO- डेवलपर- पाओलो-Pialorsi/dp/0735624003/ref=sr_1_23?ie = यूटीएफ 8 और एस = किताबें और क्यूआईडी = 1245694305 और एसआर = 8-23 –

+0

एक और वाक्यविन्यास प्रदान करने के लिए धन्यवाद! – Peter

संबंधित मुद्दे