Linq से एंटिटीज बनाम ग्रुपजोन में शामिल होते हैं


181

मैंने वेब खोजा है, लेकिन मुझे अभी भी एक सरल उत्तर नहीं मिला है। क्या कोई कृपया (सरल अंग्रेजी में) समझा सकता है कि क्या GroupJoinहै? यह एक नियमित आंतरिक से अलग कैसे है Join? यह आमतौर पर इस्तेमाल किया जाता है? क्या यह केवल विधि सिंटैक्स के लिए है? क्वेरी सिंटैक्स के बारे में क्या? एक सी # कोड उदाहरण अच्छा होगा।


MSDN के अनुसार, एक समूह में शामिल होने के लिए एक अभिव्यक्ति में शामिल होने का एक खंड है। ज्वाइन क्लॉज में अधिक जानकारी और कोड नमूने हैं। यह अनिवार्य रूप से एक आंतरिक जुड़ाव है (यदि दाएं में कोई तत्व बाएं में कोई मेल नहीं खाता है, तो आपको एक अशक्त परिणाम मिलता है); हालाँकि परिणाम समूहों में आयोजित किया जाता है।
टिम

जवाबों:


371

व्यवहार

मान लीजिए कि आपकी दो सूची हैं:

Id  Value
1   A
2   B
3   C

Id  ChildValue
1   a1
1   a2
1   a3
2   b1
2   b2

जब आप मैदान Joinपर दो सूचियाँ Idदेंगे तो परिणाम होगा:

Value ChildValue
A     a1
A     a2
A     a3
B     b1
B     b2

जब आप मैदान GroupJoinपर दो सूचियाँ Idदेंगे तो परिणाम होगा:

Value  ChildValues
A      [a1, a2, a3]
B      [b1, b2]
C      []

तो Joinमाता-पिता और बच्चे के मूल्यों का एक फ्लैट (सारणीबद्ध) परिणाम पैदा करता है।
GroupJoinपहली सूची में प्रविष्टियों की एक सूची बनाता है, प्रत्येक दूसरी सूची में शामिल प्रविष्टियों के एक समूह के साथ।

यही कारण Joinहै कि INNER JOINSQL में समतुल्य है : के लिए कोई प्रविष्टियाँ नहीं हैं C। जबकि GroupJoinसमतुल्य है OUTER JOIN: Cपरिणाम सेट में है, लेकिन संबंधित प्रविष्टियों की एक खाली सूची के साथ (एक SQL परिणाम सेट में एक पंक्ति होगी C - null)।

वाक्य - विन्यास

तो दो सूचियों IEnumerable<Parent>और IEnumerable<Child>क्रमशः होने दो । (Linq to Entities के मामले में:) IQueryable<T>

Join वाक्यविन्यास होगा

from p in Parent
join c in Child on p.Id equals c.Id
select new { p.Value, c.ChildValue }

IEnumerable<X>जहाँ एक X दो गुणों वाला एक अनाम प्रकार है, Valueऔर ChildValue। यह क्वेरी सिंटैक्स Joinहुड के तहत विधि का उपयोग करता है ।

GroupJoin वाक्यविन्यास होगा

from p in Parent
join c in Child on p.Id equals c.Id into g
select new { Parent = p, Children = g }

एक लौटने IEnumerable<Y>जहां Y एक गुमनाम प्रकार से एक संपत्ति से मिलकर प्रकार है Parentऔर प्रकार की संपत्ति IEnumerable<Child>। यह क्वेरी सिंटैक्स GroupJoinहुड के तहत विधि का उपयोग करता है ।

हम केवल select gबाद की क्वेरी में कर सकते हैं , जो IEnumerable<IEnumerable<Child>>एक सूची का चयन करेगा , सूची का चयन करेगा । कई मामलों में शामिल माता-पिता के साथ चयन अधिक उपयोगी है।

कुछ मामलों का उपयोग करते हैं

1. एक फ्लैट बाहरी शामिल होने का उत्पादन।

जैसा कि बयान में कहा गया है ...

from p in Parent
join c in Child on p.Id equals c.Id into g
select new { Parent = p, Children = g }

... बाल समूहों के साथ माता-पिता की एक सूची तैयार करता है। यह माता-पिता-बाल जोड़े की एक छोटी सूची में दो छोटे परिवर्धन द्वारा बदल दिया जा सकता है:

from p in parents
join c in children on p.Id equals c.Id into g // <= into
from c in g.DefaultIfEmpty()               // <= flattens the groups
select new { Parent = p.Value, Child = c?.ChildValue }

परिणाम के समान है

Value Child
A     a1
A     a2
A     a3
B     b1
B     b2
C     (null)

ध्यान दें कि उपरोक्त कथन में श्रेणी चर c का पुन: उपयोग किया जाता है। ऐसा करते हुए, किसी भी joinबयान को केवल मौजूदा कथन outer joinके समतुल्य जोड़कर परिवर्तित किया जा सकता है ।into g from c in g.DefaultIfEmpty()join

यह वह जगह है जहाँ क्वेरी (या व्यापक) सिंटैक्स चमकता है। विधि (या धाराप्रवाह) वाक्यविन्यास दिखाता है कि वास्तव में क्या होता है, लेकिन यह लिखना मुश्किल है:

parents.GroupJoin(children, p => p.Id, c => c.Id, (p, c) => new { p, c })
       .SelectMany(x => x.c.DefaultIfEmpty(), (x,c) => new { x.p.Value, c?.ChildValue } )

तो outer joinLINQ में एक फ्लैट एक GroupJoin, द्वारा चपटा है SelectMany

2. आदेश की रक्षा

माना कि माता-पिता की सूची थोड़ी लंबी है। कुछ यूआई Idएक निश्चित क्रम में मूल्यों के रूप में चयनित माता-पिता की सूची तैयार करता है । चलो उपयोग करें:

var ids = new[] { 3,7,2,4 };

अब चयनित माता-पिता को इस सटीक क्रम में माता-पिता की सूची से फ़िल्टर किया जाना चाहिए।

यदि हम करें तो ...

var result = parents.Where(p => ids.Contains(p.Id));

... parentsपरिणाम का क्रम निर्धारित करेगा। यदि माता-पिता द्वारा आदेश दिया जाता है Id, तो परिणाम माता-पिता 2, 3, 4, 7. अच्छा नहीं होगा। हालाँकि, हम joinसूची को फ़िल्टर करने के लिए भी उपयोग कर सकते हैं । और idsपहली सूची के रूप में उपयोग करके , आदेश संरक्षित किया जाएगा:

from id in ids
join p in parents on id equals p.Id
select p

परिणाम माता-पिता 3, 7, 2, 4 है।


तो GroupJoin में, बच्चे के मूल्यों में ऑब्जेक्ट शामिल होंगे, जिसमें संबंधित मूल्य होते हैं?
duyn9uyen

जैसा कि आपने कहा कि GroupJoin एक बाहरी जॉइन की तरह है, लेकिन सिंटैक्स (समूह में शामिल होने के लिए विशुद्ध रूप से linq) का कहना है कि यह बाहरी जॉइन की तरह नहीं है, बल्कि बाहरी जॉइन में शामिल है।
इमाद

2
मुझे लगता है कि मैं यह निर्दिष्ट करूंगा कि "फ्लैट आउटर जॉइन" एक लेफ्ट आउटर जॉइन है।
NetMage

1
पूरी तरह से समझाया, मैं अब समझता हूँ
peterincumbria

19

EduLINQ के अनुसार :

GroupJoin जो करता है उसके साथ जुड़ने के बारे में सोचने का सबसे अच्छा तरीका है। वहां, समग्र विचार यह था कि हमने "बाहरी" इनपुट अनुक्रम के माध्यम से देखा, "आंतरिक" अनुक्रम (प्रत्येक अनुक्रम पर एक महत्वपूर्ण प्रक्षेपण के आधार पर) से सभी मिलान किए गए आइटम पाए और फिर मिलान तत्वों के जोड़े का उत्पादन किया। GroupJoin समान है, सिवाय इसके कि जोड़े के तत्वों की उपज के बजाय, यह उस आइटम के आधार पर प्रत्येक "बाहरी" आइटम के लिए एक एकल परिणाम देता है और "इनर" आइटम के मिलान का क्रम

एकमात्र अंतर रिटर्न स्टेटमेंट में है:

सम्मिलित हों :

var lookup = inner.ToLookup(innerKeySelector, comparer); 
foreach (var outerElement in outer) 
{ 
    var key = outerKeySelector(outerElement); 
    foreach (var innerElement in lookup[key]) 
    { 
        yield return resultSelector(outerElement, innerElement); 
    } 
} 

GroupJoin :

var lookup = inner.ToLookup(innerKeySelector, comparer); 
foreach (var outerElement in outer) 
{ 
    var key = outerKeySelector(outerElement); 
    yield return resultSelector(outerElement, lookup[key]); 
} 

यहाँ और पढ़ें:

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.