व्यवहार
मान लीजिए कि आपकी दो सूची हैं:
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 है।