2011-12-08 25 views
6

अगर मैं एक प्रश्न है कि इस तरह दिखता है:इकाई की रूपरेखा में शामिल हैं कहाँ

SubForm कई Class जो कई Term है है:

var forms = repo.GetForms().Where(f => f.SubForms.Any(sf => sf.Classes.Any(c => c.TermId == termId))); 

इस से आप देख सकते हैं मेरी स्कीमा इस प्रकार है।

मुझे क्या करना चाहते हैं:

सभी SubForms उनके Classes साथ एक विशेष Term में।

अब क्या हो रहा है यह है कि मुझे सभी SubForm मिलते हैं जिसमें Class कोई विशेष Term है। इसका मतलब है कि SubFormसभी बच्चे Class और Term से संबंधित नहीं हैं।

उदाहरण के लिए। मेरे पास 2 शब्द हैं, प्रत्येक शब्द में 2 कक्षाओं के साथ एक सबफॉर्म। यह क्वेरी उस विशेष अवधि में 2 की बजाय 4 कक्षाएं वापस लाती है।

क्या कोई Include('Expression') है जिसका उपयोग मैं कह सकता हूं कि मैं केवल एक शर्त के आधार पर सभी वर्गों को शामिल करना चाहता हूं? या मेरी क्वेरी गलत है?

+0

पहला 'कोई भी' 'कहां 'होना चाहिए, है ना? अन्यथा आपकी क्वेरी सिर्फ 'बूल' वापस कर देगी, कह रही है, "क्या कोई सबफॉर्म है जिसमें दिए गए शब्द आईडी, हां या नहीं के साथ कक्षाएं हैं?" – Slauma

+0

@Slauma क्षमा करें, उस अभिव्यक्ति के शीर्ष पर एक और स्तर भी है, मैं इसे संपादित करूंगा, क्षमा करें –

उत्तर

0

मैं संबंधों के सटीक नाम पता नहीं है, लेकिन यह

repo.Terms 
    .Include("Classes") 
    .Include("Classes.SubForms") 
    .SingleOrDefault(x => x.TermId = termId); 

// or 

repo.GetSubForms 
    .Include("Classes") 
    .Where(sf => sf.Classes.Where(c => c.TermId == termId)); 
4

की तर्ज एक Include(Where Expression) मौजूद नहीं है के साथ कुछ किया जाना चाहिए। यदि आप शामिल करने के साथ उत्सुक लोडिंग का उपयोग करते हैं तो आप हमेशा सभी तत्वों को लोड करेंगे।

अनुमानों का उपयोग करके इसके आसपास एक तरीका है। मूल विचार यह है कि आप अपनी इच्छित संपत्ति के साथ एक नया अनाम प्रकार और फ़िल्टर किए गए नेविगेशन आइटम वाली दूसरी संपत्ति का चयन करेंगे। ईएफ उनको एक साथ जोड़ देगा और नतीजतन आप नकली Include(Where ...)

Check this for an example नकली करेंगे।

+1

मामूली नाइट: 'शामिल करें (अभिव्यक्ति)' सिस्टम के रूप में मौजूद है। डेटा.एन्टीटी.डीबी एक्सटेंशन। एक्सटेंशन विधि शामिल करें, लेकिन एक बिल्कुल अलग अर्थ है। इसे स्ट्रिंग अक्षर के विकल्प के रूप में उपयोग किया जाता है: 'repo.Terms.Include (term => term.Classes) '। – hvd

+0

Thnx। मैंने अपना उत्तर –

0

यह एक आम अनुरोध प्रतीत होता है, जब मैं इस साल की शुरुआत में था तो इसका समाधान ढूंढना मुश्किल था। मैं नीचे दिए गए लिंक में शामिल समाधान का उपयोग कर समाप्त हुआ (मुझे यकीन नहीं है कि यह सही समाधान है जो मैंने पाया, लेकिन यह वही विचार है)। उम्मीद है की यह मदद करेगा!

Filter the "Includes" table on Entity Framework query

   //Found this method to filter our child objects instead of using .include() 
       var Results = (from res in 
            (from u in DataContext.User 
            where u.Type.ToUpper() != "ADMIN" 
            && u.StartDate <= DateTime.Now 
            && (u.EndDate == null || u.EndDate >= DateTime.Now) 
            select new 
            { 
             User = u, 
             Access = u.Access.Where(a => a.StartDate <= DateTime.Now 
                && (a.EndDate == null || a.EndDate >= DateTime.Now)) 
            } 
            ) 
           select res); 

       //The ToArray is neccesary otherwise the Access is not populated in the Users 
       ReturnValue = Results.ToArray().Select(x => x.User).ToList(); 
6

उपयोग करें:

var subForms = repo.GetSubForms.Select(sf = new { 
     SubForm = sf, 
     Classes = sf.Classes.Where(c => c.TermId == termId) 
    }).ToList() 
    .Select(t => t.SubForm) 
    .ToList(); 

अद्यतन: @ Slauma की टिप्पणी के आधार पर:

आप SubForm रों लोड करने के लिए वे किसी भी Class है कि है कि चाहते हैं TermtermId द्वारा, आप अंत से जा सकते हैं शुरू करने के लिए; इस तरह:

var subForms = repo.Terms.Where(t => t.Id == termId).Select(t => new { 
     Term = t, 
     Class = t.Class, 
     SubForm = t.Class.SubForm 
    }).ToList() 
    .Select(t => t.SubForm).ToList(); 

या एक सबसे आसान तरीका है, आप अपने Term पर Include उपयोग कर सकते हैं में, देखें:

var subForms = repo.Terms.Include("Class.SubForm").Where(t => t.Id == termId) 
        .Select(t => t.Class.SubForm).ToList(); 

नोट: मैं अपने प्रश्न से समझ सकते हैं के रूप में, आप एक है इस तरह के रिश्ते:

SubForm has_many Class has_many Term 

लेकिन, आपका प्रदत्त कोड ar दिखा रहा है इस तरह elationship:

SubForm has_many Class 
Term has_many Class 

आप, सवाल में अपनी संस्थाओं डाल सकते हैं, या उनके रिश्ते और अधिक व्याख्या करते हैं तो कृपया। धन्यवाद।

+1

संशोधित कर दिया है आपको अभी भी 'GetSubForms' और' select' 'के बीच फ़िल्टर की आवश्यकता है:' कहाँ (sf => sf.Classes.Any (c => c.TermId == termId)) '। अन्यथा आप डीबी से * सभी * सबफॉर्म लोड करेंगे, जिसमें कक्षाओं के साथ सबफॉर्म शामिल नहीं होंगे। – Slauma

+0

@ स्लुमा ओके, वास्तव में मैं पूरी तरह से प्रश्न को समझ नहीं पा रहा हूं; तो मैं अपना जवाब अपडेट करता हूं; धन्यवाद :) –

+1

सच है, प्रश्न में पहला 'कोई भी' उलझन में है। मैंने अभी प्रश्न के तहत एक टिप्पणी लिखी है क्योंकि मुझे विश्वास है कि वह वास्तव में 'कहां' था। – Slauma

1

आप कभी-कभी जानते हैं कि मैं फैंसी LINQ एक्सटेंशन विधियों में खो जाना शुरू कर रहा हूं और यह पता लगाने का प्रयास कर रहा हूं कि मैं जो चाहता हूं उसे उत्सुकता से लोड करना और एक बहुत ही सरल "शामिल" अवधारणा का सहारा लेना चाहता हूं।

var result = 
(from f in SubForums 
from c in Classes 
from t in Term 
where t.TermId = 1 
select new { SubForum = f, Class = c, Term = t }).ToList(); 

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

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