2011-08-16 16 views
19

यहां समस्या है: मुझे फ़िल्टर किए गए नेस्टेड संग्रहों के साथ ऑब्जेक्ट्स का संग्रह वापस करने की आवश्यकता है। E.g: ऑर्डर वाले स्टोर हैं और मुझे स्टोर के साथ एक संग्रह वापस करने की आवश्यकता है जिसमें ऑर्डर के साथ नेस्टेड संग्रह शामिल हैं लेकिन हटाए गए ग्राहकों के आदेशों के बिना।नेस्टेड संग्रह इकाई फ्रेमवर्क ऑब्जेक्ट्स को फ़िल्टर कैसे करें?

मैं यही करने की कोशिश करता हूं। लेकिन अभी भी कोई भाग्य नहीं है। किसी भी सुझाव की सराहना की जाती है :)

public List<StoreEntity> GetStores(Func<Store, bool> storeFilter, Predicate<OrderEntity> orderFileter) 
{ 
    IQueryable<StoreEntity> storeEntities = Context.Stores 
     .Include(o => o.Order) 
     .Include(cu => cu.Orders.Select(c => c.Customer)) 
     .Where(storeFilter) 
     //.Where(rcu=>rcu.Orders.Select(cu=>cu.Customer.Deleted==false)) //just test this doesn't work 
     .AsQueryable(); 

    List<StoreEntity> storeEntities = storeEntities.ToList(); 

    //storeEntities.ForEach(s => s.Orders.ToList().RemoveAll(c=>c.Customer.Deleted==true)); // doesn't work 

    foreach (StoreEntity storeEntity in storeEntities) 
    { 
     storeEntity.Orders.ToList().RemoveAll(r=>r.Customer.Deleted==true); 
    } 

    return storeEntities; 
} 

समस्या यह है कि फ़िल्टर लागू नहीं होता है। जिन ग्राहकों ने संग्रह में सही रहने के रूप में ध्वज सेट हटा दिया है।

+0

और समस्या क्या है? क्या यह संकलित नहीं है? क्या यह रनटाइम अपवाद फेंकता है?क्या यह चल रहा है लेकिन गलत डेटा लौटाता है? –

+0

थोड़ा और समझाया। धन्यवाद। –

+1

मैं इस nuget पैकेज का उपयोग कर समाप्त हुआ: 'Z.EntityFramework.Plus.QueryIncludeFilter.EF6' यहां प्रलेखन: https://github.com/zzzprojects/EntityFramework-Plus/wiki/EF-Query-IncludeFilter-%7C-Entity- फ्रेमवर्क-शामिल-संबंधित-संस्थाएं-उपयोग-कहां फ़िल्टर –

उत्तर

26

आप इसे सीधे "साफ" तरीके से नहीं कर सकते हैं, लेकिन आपके पास कुछ विकल्प हैं।
सबसे पहले, आप स्पष्ट रूप से स्टोर संग्रह प्राप्त करने के बाद बच्चे संग्रह को लोड कर सकते हैं। Applying filters when explicitly loading related entities अनुभाग देखें।

यदि आप डेटाबेस में अतिरिक्त यात्रा नहीं करना चाहते हैं, तो आपको अपनी खुद की क्वेरी बनाना होगा और मूल संग्रह और फ़िल्टर किए गए बाल संग्रह को अन्य ऑब्जेक्ट पर मैन्युअल रूप से प्रोजेक्ट करना होगा। उदाहरण के लिए निम्नलिखित प्रश्न देखें:
Linq To Entities - how to filter on child entities
LINQ Query - how sort and filter on eager fetch

संपादित

वैसे, अपने पहले .Where(rcu=>rcu.Orders.Select(cu=>cu.Customer.Deleted==false)) प्रयास इस तरह से आप अपने माता पिता संग्रह पर एक फ़िल्टर लागू कर रहे हैं के बाद से काम नहीं करता है (भंडार) नेस्टेड संग्रह की बजाय (उदाहरण के लिए सभी स्टोर जो ग्राहकों को हटा नहीं चुके हैं)।
तार्किक रूप से, नेस्टेड संग्रह को फ़िल्टर करने वाला कोड Include विधि में रखा जाना चाहिए। वर्तमान में, Include केवल एक Select बयान का समर्थन करता है, लेकिन व्यक्तिगत रूप से मुझे लगता है कि एफई टीम की तरह कुछ को लागू करने के लिए समय है:

storeEntity.Orders.ToList().RemoveAll(r=>r.Customer.Deleted==true); 

:

.Include(cu => cu.Orders.Select(c => c.Customers.Where(cust => !cust.IsDeleted))); 
+0

हाँ, मैं सहमत हूं। (मुझे पता है कि चीज काम नहीं करती है, लेकिन फिर भी इसे आजमा देना चाहती है, जो जानता है कि यह सुविधा छिपी हुई थी और मुझे सुखद आश्चर्य होगा), और हां, इस तरह के शामिल होना अच्छा होगा। मैंने कस्टम प्रक्षेपण के साथ जाने का फैसला किया ... वास्तव में उस विधि को पसंद नहीं करते क्योंकि मुझे बहुत सारे बेवकूफ मूल्यों को असाइन करना था जैसे कि (आईडी = r.ID, नाम = r.Name ... और इसी तरह)। लेकिन कम से कम यह काम करता है :) Thx –

+3

मैं सहमत हूं कि ईएफ टीम को फ़िल्टर किए गए लागू करना चाहिए। इसके लिए वोट दें [यहां] (https://entityframework.codeplex.com/workitem/47)! – Chris

+0

क्या मैं एक सामान्य विधि कहा जाता है, तो 'GetWithInclude()' 'सार्वजनिक IQueryable GetWithInclude (पैरामीटर अभिव्यक्ति <समारोह > [] includeProperties) { वापसी includeProperties.Aggregate <अभिव्यक्ति <समारोह >, IQueryable > (डीबीसेट, (वर्तमान, शामिल प्रॉपर्टी) => वर्तमान। शामिल करें (शामिल प्रॉपर्टी)); } ' फिर भी, मेरे पास संग्रह नहीं है और मुझे प्रक्षेपण से फ़िल्टर की आवश्यकता है। दूसरे शब्दों में, मेरे पास एक ऐसी संपत्ति है जिसे कुछ बराबर करने की आवश्यकता है। – Vyache

2

कोड आप वर्तमान में है के साथ समस्या यह इस लाइन है storeEntity.Orders.ToList() की सामग्री के साथ नयाList<OrderEntity> देता है। इस नई सूची से, आप सभी हटाए गए ग्राहकों को हटा दें। हालांकि, इस सूची का उपयोग उसके बाद कहीं भी नहीं किया जाता है।

हालांकि, अगर आप ऐसा करना चाहते हैं, तो भी यह उन ग्राहकों को डेटाबेस से हटा देगा, क्योंकि आपकी StoreEntity ऑब्जेक्ट्स डेटा संदर्भ से अभी भी जुड़े हुए हैं!

आप वास्तव में एक फ़िल्टर का उपयोग करना चाहते हैं जैसा आपने पहले टिप्पणी की थी Where। कृपया उस पर मदद के लिए याकिमिच का जवाब देखें।

-5

पुराना विषय, लेकिन मैं एक समान समस्या में भाग गया। मैंने बहुत कुछ खोजा है, और यकीमिक द्वारा प्रदान किए गए एमएसडीएन लिंक ने अंततः मुझे एक समाधान के लिए संकेत दिया: आलसी लोडिंग को स्पष्ट रूप से अक्षम करें, और फिर नेविगेशन गुणों को फ़िल्टर करने के लिए क्वेरी करें। नतीजा तब मुख्य प्रश्न के लिए "संलग्न" होगा, जो कुछ ऐसा देगा:

Context.Configuration.LazyLoadingEnabled = false; 

var filteredOrders = Context.Orders.Where(x => x.Customer.Delete == false); 

IQueryable<StoreEntity> storeEntities = Context.Stores 
.Include(o => o.Order) 
.Include(cu => cu.Orders.Select(c => c.Customer)) 
.Where(storeFilter) 
.AsQueryable(); 
+0

स्टोरफिल्टर क्या है? –

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