2009-07-06 17 views
21

मुझे लगा जैसे निम्नलिखित संभव होना चाहिए मुझे यकीन नहीं है कि क्या दृष्टिकोण लेना है।सशर्त में linq में इकाइयों में शामिल हैं?

मैं जो करना चाहता हूं वह मेरे परिणामों को आकार देने के लिए शामिल विधि का उपयोग करना है, यानी परिभाषित करें कि ऑब्जेक्ट ग्राफ़ को ट्रैवर्स के साथ कितना दूर रखा गया है। लेकिन ... मैं उस ट्रैवर्सल को सशर्त होना चाहता हूं।

something like... 

dealerships 
    .include(d => d.parts.where(p => p.price < 100.00)) 
    .include(d => d.parts.suppliers.where(s => s.country == "brazil")); 

मैं समझता हूँ कि यह वैध LINQ, वास्तव में नहीं है, यह बहुत गलत है, लेकिन अनिवार्य रूप से मैं किसी तरह एक अभिव्यक्ति पेड़ कि आकार का परिणाम है, के बराबर वापस आ जाएगी का निर्माण करने के लिए देख रहा हूँ ...

select * 
from dealerships as d 
outer join parts as p on d.dealerid = p.dealerid 
    and p.price < 100.00 
outer join suppliers as s on p.partid = s.partid 
    and s.country = 'brazil' 

शामिल स्थितियों पर जोर देने के साथ।

मुझे लगता है कि यह एस्कल के साथ काफी सीधे आगे होगा लेकिन मेरी वरीयता फ्लाई पर अभिव्यक्ति पेड़ बनाना होगा।

हमेशा की तरह, किसी भी सलाह या मार्गदर्शन

+1

क्या आपको कभी इसका समाधान मिला? मुझे भी यही समस्या हो रही है। –

+0

अभी तक नहीं, लेकिन मैं दिलचस्पी रखता हूं और आगे बढ़ना जारी रखूंगा ... – tim

+0

मैं वही चीज़ ढूंढ रहा था –

उत्तर

15

इस चाल करना चाहिए:

using (TestEntities db = new TestEntities()) 
{ 
    var query = from d in db.Dealership 
       select new 
       { 
        Dealer = d, 
        Parts = d.Part.Where 
        (
         p => p.Price < 100.0 
          && p.Supplier.Country == "Brazil" 
        ), 
        Suppliers = d.Part.Select(p => p.Supplier) 
       }; 

    var dealers = query.ToArray().Select(o => o.Dealer); 
    foreach (var dealer in dealers) 
    { 
     Console.WriteLine(dealer.Name); 
     foreach (var part in dealer.Part) 
     { 
      Console.WriteLine(" " + part.PartId + ", " + part.Price); 
      Console.WriteLine 
       (
       " " 
       + part.Supplier.Name 
       + ", " 
       + part.Supplier.Country 
       ); 
     } 
    } 
} 

इस कोड को आप डीलरशिप प्रत्येक भागों की फ़िल्टर की गई सूची से युक्त की एक सूची दे देंगे। प्रत्येक भाग एक प्रदायक संदर्भित करता है। दिलचस्प हिस्सा यह है कि आपको दिखाए गए तरीके में चयन में अनाम प्रकार बनाना होगा। अन्यथा डीलरशिप वस्तुओं की पार्ट संपत्ति खाली होगी।

इसके अलावा, आपको क्वेरी से डीलरों का चयन करने से पहले SQL कथन निष्पादित करना होगा। अन्यथा डीलरों की पार्ट संपत्ति फिर से खाली हो जाएगी।

var dealers = query.ToArray().Select(o => o.Dealer); 

लेकिन मैं डैरेन के साथ सहमत नहीं हो सकता है कि क्या अपने पुस्तकालय के उपयोगकर्ताओं की उम्मीद कर रहे: यही कारण है कि मैं निम्न पंक्ति में toArray() कॉल कर दिया है।

+2

इस पर एक नोट, मैंने कोशिश की और यह शुरुआत में काम नहीं किया। अंततः मुझे पता चला कि मुझे आलसी लोडिंग चालू हुई जिस पर यह काम नहीं कर रहा था। एक बार जब मैं आलसी लोडिंग बंद कर दिया तो यह एक आकर्षण की तरह काम किया। धन्यवाद जैकोब! – msmucker0527

+5

इसके लिए आपको वास्तविक संदर्भों के साथ कच्चे प्रकार के बजाय एक अनाम प्रकार वापस करने की आवश्यकता है। यह "काम करता है" लेकिन मुझे कच्चे ऑब्जेक्ट को वास्तविक संग्रह ऑब्जेक्ट के साथ वापस करने का समाधान छोड़ देता है जिसे मैं वास्तव में वापस लौटना चाहता था। अनाम वापसी प्रकार निश्चित रूप से काम करता है ... लेकिन वास्तव में वास्तव में वांछित समाधान नहीं है। – VulgarBinary

+0

@VulgarBinary आप इस प्रकार एक टाइप की गई सूची वापस कर सकते हैं: 'var dealers = query.ToArray()। चुनें (o => o.Dealer) .सूची();' यह बस काम करता है! –

1

के लिए आभारी मैं कुछ याद आ रही हूँ, या आप बस Any कीवर्ड के लिए नहीं देख रहे हैं?

var query = dealerships.Where(d => d.parts.Any(p => p.price < 100.00) || 
           d.parts.suppliers.Any(s => s.country == "brazil")); 
+2

मुझे ऐसा नहीं लगता है, जैसा कि मैं इसे समझता हूं, यह डीलरशिप वापस करेगा जहां भागों और आपूर्तिकर्ताओं से मिले थे सभी डीलरशिप वापस करने के बजाय, 100 से कम के सभी हिस्सों और ब्राजील में सभी आपूर्तिकर्ताओं को वापस करने की बजाय स्थितियां। मुझे एहसास है कि यह एक बाहरी शामिल होना चाहिए। मुझे लगता है कि मैं जो करने की कोशिश कर रहा हूं वह पेड़ के नीचे मूल्यों के आधार पर शीर्ष स्तर के नोड्स फ़िल्टर करने के बजाय परिणामों के वृक्ष को प्रतिबिंबित करता है। – tim

6

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

या दूसरे शब्दों में कहें, यदि मैं अपने परिणाम से बाहर एक डीलरशिप खींच सकते हैं और एक विधि मैंने लिखा करने के लिए पारित किया है, और फिर मेरी विधि में मैं फोन:

var count = dealership.Parts.Count(); 

मैं पाने के लिए उम्मीद कर रहा हूँ भागों, ब्राजील से फ़िल्टर किए गए हिस्सों में नहीं, जहां कीमत $ 100 से कम है।

यदि आप फ़िल्टर किए गए डेटा को पास करने के लिए डीलरशिप ऑब्जेक्ट का उपयोग नहीं करते हैं, तो यह बहुत आसान हो जाता है।

var query = from d in dealerships 
       select new { DealershipName = d.Name, 
CheapBrazilProducts = dealership.Parts.Where(d => d.parts.Any(p => p.price < 100.00) || d.parts.suppliers.Any(s => s.country == "brazil")) }; 

तो मैं बस से फ़िल्टर सेट की तरह आप से पूछा, मैं शायद तकनीक मैं उपर्युक्त का उपयोग करेंगे, और फिर Automapper तरह से फ़िल्टर किए गए परिणामों को कॉपी करने के लिए एक उपकरण का उपयोग पाने के लिए था: यह रूप में सरल हो जाता है असली कक्षा में मेरी अज्ञात कक्षा। यह अविश्वसनीय रूप से सुरुचिपूर्ण नहीं है, लेकिन यह काम करना चाहिए।

मुझे उम्मीद है कि इससे मदद मिलती है! यह एक दिलचस्प समस्या थी।

+0

धन्यवाद डैरेन मैं ऑब्जेक्ट पहचान के रूप में अब तक सहमत हूं! मैं भी चिंतित हूं कि, यही कारण है कि यह ईएफ द्वारा समर्थित नहीं हो सकता है। क्या मैं सच में यहाँ करने के लिए कोशिश कर रहा हूँ ब्राजील क्वेरी स्ट्रिंग जैसे http://carpartsdb.com/dealerships/parts(price <100)/आपूर्तिकर्ताओं (s.country ==) एक में पार्स है क्वेरी एक्सप्रेशन और ईएफ पर जांचें, एक कस्टम एक्सएमएल सीरियलाइजेशन रणनीति में चक करें और पस्टो आपके पास एक रेस्टक्लुएल इंजन (आराम से क्वेरी भाषा) है। मैं ईएफ से भी बंधे नहीं हूं लेकिन मॉडल अबास्ट्रक्शन और अभिव्यक्ति पेड़ और ईएफ सक्षम होना चाहते हैं और एमएस स्टैक से बहुत दूर विचलित नहीं होना चाहते हैं! – tim

+0

क्षमा करें डारन, इस पाठ को और उत्तर में देखें जहां यह और अधिक पठनीय होगा! – tim

0

हां यही मैं करना चाहता था, मुझे लगता है कि डेटा सेवाओं के अगले पुनर्विक्रय के पास केवल LINQ से REST क्वेरी करने की संभावना होगी जो कि उस समय में बहुत अच्छा होगा जब मैंने उलटा लोड करने के लिए स्विच किया था और संबंधित शामिल किया था इकाई है कि कई बार लोड किया जाएगा, लेकिन सिद्धांत रूप में यह सिर्फ इससे पहले कि मैं किसी भी searchHistories उस तर्क का मिलान नहीं हुआ संभाल के लिए लोड करने का प्रयास इस कोड

return this.Context.SearchHistories.Include("Handle") 
    .Where(sh => sh.SearchTerm.Contains(searchTerm) && sh.Timestamp > minDate && sh.Timestamp < maxDate); 

में की तरह एक बार लोड करने के लिए पहले शामिल है, लेकिन पता नहीं है आपके द्वारा पोस्ट किए गए तर्क को शामिल करने का अर्थ यह है कि मुझे लगता है कि एक रिवर्स लुकअप एक गंदे समाधान नहीं होगा

0

मुझे पता है कि यह एक एकल शामिल के साथ काम कर सकते हैं। दो के साथ परीक्षण कभी भी शामिल नहीं है, लेकिन कोशिश करने लायक है:

dealerships 
    .Include(d => d.parts) 
    .Include(d => d.parts.suppliers) 
    .Where(d => d.parts.All(p => p.price < 100.00) && d.parts.suppliers.All(s => s.country == "brazil")) 
संबंधित मुद्दे