2009-08-12 11 views
22

मुझे AND एस की बजाय OR एस स्थितियों में बाएं से जुड़ने की आवश्यकता है। मुझे बाद के बहुत सारे नमूने मिल गए हैं लेकिन मेरे परिदृश्य के लिए सही जवाब पाने के लिए संघर्ष कर रहा हूं।लिंक - एकाधिक (OR) स्थितियों पर बाएं शामिल हों

from a in tablea 
join b in tableb on new { a.col1, a.col2 } equals new { b.col1, b.col2 } 
group a by a into g 
select new() { col1 = a.col1, col2 = a.col2, count = g.Count() } 

उन सभी जोड़ों के लिए बहुत अच्छा काम करता है जहां सभी शर्तों का मिलान होना चाहिए। मुझे on a.col1 = b.col1 OR a.col2 = b.col2 से मिलान करने के लिए शामिल होने की आवश्यकता है।

मुझे पता है कि यह आसान होना चाहिए लेकिन मैं इस पर खाली आ रहा हूं!

संपादित करें:

थोड़ी और जानकारी देने के लिए, क्वेरी करने के उद्देश्य से एक प्रक्षेपण 'एक' 'बी' में मिलान रिकॉर्ड की गिनती के साथ साथ से क्षेत्रों के सभी युक्त पाने के लिए है। मैंने ऊपर दिए गए नमूने में संशोधन किया है ताकि मैं कोशिश कर सकूं कि मैं क्या कर रहा हूं। जब मैं उपरोक्त के साथ दौड़ता हूं तो जॉन स्कीट ने ध्यान दिया है कि मुझे बी से संबंधित रिकॉर्ड की गिनती नहीं, सभी रिकॉर्डों की गिनती मिल रही है।

बुनियादी बाईं काम करता है में शामिल होने के ठीक:

from a in tablea 
from b in tableb 
.Where(b => (a.col1 == b.col1 || a.col2 == b.col2)) 
.DefaultIfEmpty() 
select new { col1 = a.col1, col2 = a.col2 } 

अगर मैं इस पर संशोधन के रूप में नीचे

from a in tablea 
from b in tableb 
.Where(b => (a.col1 == b.col1 || a.col2 == b.col2)) 
.DefaultIfEmpty() 
group a by a.col1 into g 
select new { col1 = g.Key, count = g.Count() } 

मैं रिकॉर्ड की गिनती हो रही है समूह जोड़ने के लिए एक से लौटे - नहीं बी में मिलान में रिकॉर्ड की गिनती।

संपादित करें:

मैं जॉन का जवाब दे देंगे - मैं अपने गिनती समस्या हल हो जाती है - मैंने महसूस नहीं किया था मैं गिनती (g.Count(x => x != null)) फिल्टर करने के लिए एक lamda इस्तेमाल कर सकते हैं। इसके अलावा मुझे ऊपर की तरह एक के बजाय बी को समूहित करने की आवश्यकता है। यह सही परिणाम देता है लेकिन एसक्यूएल उतना कुशल नहीं है जितना मैं इसे हाथ से लिखूंगा क्योंकि यह एक सहसंबंधित उप क्वेरी जोड़ता है - अगर कोई निम्नलिखित एसक्यूएल को अनुकरण करने के लिए इसे लिखने का बेहतर तरीका सुझा सकता है तो मैं इसकी सराहना करता हूं!

select a.col1, count(b.col1) 
from tablea a 
left join tableb b 
on a.col1 = b.col1 
or a.col2 = b.col2 
group by a.col1 
+0

मेरा सुझाव है कि आप समूह के बिना * मेरी क्वेरी * कोशिश करें, और देखें कि क्या आपको उम्मीदें मिल रही हैं या नहीं। यदि ऐसा होता है, तो समूहिंग विफल होने का कारण बनने का प्रयास करें। शायद 'नया {a.col1, a.col2}' द्वारा समूह? –

+0

एक मूल बाएं शामिल होने के रूप में ठीक काम करता है - ग्रुपिंग से गिनती प्राप्त करना व्यवहार नहीं कर रहा है क्योंकि मुझे उम्मीद है कि यह मूलभूत इक्विटी-इन होगा। ऊपर अतिरिक्त जानकारी नोट करें। –

उत्तर

32

LINQ केवल इक्विजिन्स का समर्थन करता है। आप में शामिल होने की किसी भी अन्य प्रकार क्या करना चाहते हैं, तो आप मूल रूप से एक की जरूरत है पार में शामिल होने और where:

from a in tablea 
from b in tableb 
where a.col1 == b.col1 || a.col2 == b.col2 
select ... 

यह शायद जाँच के लायक है क्या उत्पन्न एसक्यूएल की तरह लग रहा है और क्या क्वेरी योजना की तरह है। ऐसा करने के अधिक कुशल तरीके हो सकते हैं, लेकिन शायद यह सरलतम दृष्टिकोण है। , यदि आप एक DB पर अमल बस के रूप में कुशल हो जाएगा

from a in tablea 
from b in tableb 
where a.col1 == b.col1 || a.col2 == b.col2 

कौन सा,:

+0

मैंने इस दृष्टिकोण के साथ शुरुआत की है ... मैं वास्तव में प्रश्न से समूह में प्रवेश कर रहा हूं और बी से मेल खाने वाले रिकॉर्ड की गिनती प्राप्त कर रहा हूं। मैं स्पष्टीकरण के लिए पोस्ट संपादित करूंगा। –

20

क्वेरी प्रदाता के आधार पर, तुम बस खंड से दो का उपयोग करने के लिए चुन सकते हैं। यदि आप इन-मेमोरी (ऑब्जेक्ट्स के लिए लिंक) निष्पादित करते हैं, तो यह सभी संभावित संयोजनों का आकलन करेगा, जो अक्षम हो सकते हैं।

Arg, Skeeted ;-)।

ऑब्जेक्ट्स विकल्प के लिए अधिक कुशल लिंक संभव है। join ऑपरेटर प्रत्येक स्रोत को केवल एक बार बताता है, और उसके बाद हैश-जॉइन करता है, ताकि आप दो अलग-अलग जोड़ों में या खंड को विभाजित कर सकें, और फिर अपना संघ ले सकें।LINQ में एक संघ डुप्लिकेट के बिना सिर्फ एक संयोजन है, ताकि इस प्रकार दिखेगा:

(from a in tablea 
join b in tableb on a.Col1 equals b.Col1 
select new {a, b}) 
.Concat(
from a in tablea 
join b in tableb on a.Col2 equals b.Col2 
select new {a, b} 
).Distinct() 

यह दृष्टिकोण काम करता है, और यह सिर्फ एक क्वेरी है, लेकिन यह समझ में कुछ गैर स्पष्ट है कि के प्रदर्शन विशेषताओं कोड विस्तार से समझने पर निर्भर करता है कि linq कैसे काम करता है। निजी तौर पर, यदि आप संभावित एकाधिक मैचों के साथ हैश-जॉइन करना चाहते हैं, तो एक और स्पष्ट टूल ToLookup है। का उपयोग कर के रूप में लग सकता है एक वैकल्पिक प्रकार है:

var bBy1 = tableb.ToLookup(b=>b.Col1); 
var bBy2 = tableb.ToLookup(b=>b.Col2); 
var q3 = 
    from a in tablea 
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct() 
    ... 

यह समाधान वास्तव में कम है, और कारण यह काम करता है और अधिक स्पष्ट है, इसलिए यह एक मैं पसंद करेंगे है। बस याद रखें कि यदि आप || ऑपरेटर को दो अलग-अलग प्रश्नों में विभाजित करते हैं जैसे कि उपर्युक्त दो परिदृश्यों में आपको परिणामों को डबल-गिनती से मैन्युअल रूप से टालने की आवश्यकता है (यानी Distinct का उपयोग करें)।

+0

मैं वस्तुओं से लिंक का उपयोग कर रहा हूं - क्या कोई वैकल्पिक समाधान है? – Kev

+0

निश्चित रूप से, संपादन देखें! –

+0

मुझसे जुड़ने की देखभाल? : http://chat.stackoverflow.com/rooms/info/17239/kryptonite – Kev

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