व्यवहार
मान लीजिए कि आपकी दो सूची हैं:
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 JOIN
SQL में समतुल्य है : के लिए कोई प्रविष्टियाँ नहीं हैं 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 join
LINQ में एक फ्लैट एक 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 है।