एंटिटी फ्रेमवर्क - गुणों के कई स्तरों को शामिल करें


376

शामिल करें () विधि वस्तुओं पर सूचियों के लिए काफी अच्छी तरह से काम करती है। लेकिन क्या होगा अगर मुझे दो स्तरों पर जाने की आवश्यकता है? उदाहरण के लिए, नीचे दी गई विधि यहाँ दिखाए गए गुणों के साथ ApplicationServers को लौटाएगी। हालाँकि, ApplicationsWithOverrideGroup एक अन्य कंटेनर है जो अन्य जटिल वस्तुओं को रखता है। क्या मैं उस संपत्ति पर भी शामिल कर सकता हूं? या मैं उस संपत्ति को पूरी तरह से कैसे लोड कर सकता हूं?

जैसा कि यह अब खड़ा है, यह विधि:

public IEnumerable<ApplicationServer> GetAll()
{
    return this.Database.ApplicationServers
        .Include(x => x.ApplicationsWithOverrideGroup)                
        .Include(x => x.ApplicationWithGroupToForceInstallList)
        .Include(x => x.CustomVariableGroups)                
        .ToList();
}

केवल सक्षम संपत्ति (नीचे) और नहीं अनुप्रयोग या CustomVariableGroup गुण (नीचे) आबाद होगा। मैं यह कैसे कर सकता हूँ?

public class ApplicationWithOverrideVariableGroup : EntityBase
{
    public bool Enabled { get; set; }
    public Application Application { get; set; }
    public CustomVariableGroup CustomVariableGroup { get; set; }
}

नमस्ते, Expression must be a member expressionजब मैं यह कोशिश करता हूं तो मुझे एक अपवाद क्यों मिलता है : एक संग्रह और फिर एक स्तर नीचे एक संग्रह शामिल करने के लिए query.Include(e => e.Level1Collection.Select(l1 => l1.Level2Collection)):।
जो.वांग

1
@ थोबॉर्न, मेरे पास एक ही मुद्दा है .. मेरे मामले में, घोंसले के शिकार कई परतों के नीचे जाते हैं, मैं एक बिंदु को शामिल करने में कामयाब रहा। SQL में जो उत्पन्न हुआ, मैं देख सकता था कि सभी कॉलम c1, c2 जैसे कुछ अन्य नामों के साथ लौट रहे हैं। मेरा सवाल यह है कि मैं अपने सभी में से एक नेस्टेड डीटीओ संग्रह कैसे बना सकता हूं :( .. हो सकता है कि आप उपरोक्त उदाहरण खुद ले सकें, इसमें हम बिना किसी कस्टम डीटीओ के सभी कॉलम लौटा रहे हैं (जो खुद डीटीओ का संग्रह है )
TechQuery

जवाबों:


703

ईएफ 6 के लिए

using System.Data.Entity;

query.Include(x => x.Collection.Select(y => y.Property))

लैम्ब्डा में उस using System.Data.Entity;के संस्करण को प्राप्त करने के लिए जोड़ना सुनिश्चित करें Include


ईएफ कोर के लिए

नई विधि का उपयोग करें ThenInclude

query.Include(x => x.Collection)
     .ThenInclude(x => x.Property);

1
मैं ApplicationsWithOverrideGroup पर शामिल नहीं कर सकता ()। यह अंतर्मुखता में नहीं दिखता है।
बॉब हॉर्न

मैं आपके संपादन का उपयोग नहीं कर सकता क्योंकि ApplicationsWithOverrideGroup एक सूची है। एप्लिकेशन सूची में प्रत्येक आइटम पर एक संपत्ति है, सूची में ही नहीं।
बॉब हॉर्न

1
आह, लेकिन आपके द्वारा प्रदान किया गया लिंक उत्तर प्रदान करता है। मुझे यह कोशिश करने दें: एक संग्रह और फिर एक स्तर नीचे एक संग्रह शामिल करने के लिए: query.Include (e => e.Level1Collection.Select (l1 => l1.Level2Collection))।
बॉब हॉर्न

60
याद रखें कि System.Data.Entity को usings में शामिल करें। अन्यथा Intellisense आपको केवल विधि के शामिल (स्ट्रिंग पथ) संस्करण देगा।
OJ Raqueño

5
@ आपको Includeप्रत्येक संपत्ति के लिए कॉल करने की आवश्यकता है :Db.States.Include(state => state.Cities.Select(city => city.Customers).Include(state => state.Cities.Select(city => city.Vendors)
डिएगो टोरेस

72

अगर मैं आपको सही ढंग से समझता हूं तो आप नेस्टेड गुणों के बारे में पूछ रहे हैं। यदि ऐसा है तो :

.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)

या

.Include("ApplicationsWithOverrideGroup.NestedProp")  

या

.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")  

6
धन्यवाद, मैं कोशिश कर सकता हूँ कि। मैं उम्मीद कर रहा था कि चीजों को दृढ़ता से टाइप करने और स्ट्रिंग शाब्दिक से बचने में सक्षम होने में सक्षम हो। लेकिन अगर ऐसा है तो इसे पूरा करना होगा ...
बॉब हॉर्न

1
तुम पास थे। मैं स्पष्ट नहीं हो सकता है कि ApplicationsWithOverrideGroup एक सूची थी। मदद के लिए धन्यवाद!
बॉब हॉर्न

@ जूडो, मेरे पास एक ही मुद्दा है .. मेरे मामले में, घोंसले के शिकार कई परतों को गहरा कर देता है, मैं आपको शामिल करने में कामयाब रहा। SQL में जो उत्पन्न हुआ, मैं देख सकता था कि सभी कॉलम c1, c2 जैसे कुछ अन्य नामों के साथ लौट रहे हैं। मेरा सवाल यह है कि मैं अपने सभी में से एक नेस्टेड डीटीओ संग्रह कैसे बना सकता हूं :( .. हो सकता है कि आप उपरोक्त उदाहरण खुद ले सकें, इसमें हम बिना किसी कस्टम डीटीओ के सभी कॉलम लौटा रहे हैं (जो खुद डीटीओ का संग्रह है )
TechQuery

2
याद रखें कि System.Data.Entity को usings में शामिल करें । अन्यथा Intellisense केवल आपको Include(string path)विधि का संस्करण देगा ।
एलेक्समेल्व

52

EF कोर: म्यूटेंट लेवल को लोड करने के लिए "ThenInclude" का उपयोग करना: उदाहरण के लिए:

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
    .ToList();

53
ऐसा लगता है कि केवल ईएफ कोर है
क्रिस मैरिक जूल

27
FYI करें: VS2017 इंटेलीजेंस .ThenInclude के लिए काम नहीं कर रहा था। बस इसे टाइप करें कि आप कैसे सोचते हैं कि यह होना चाहिए और हाइलाइटिंग त्रुटि दूर जाना चाहिए।
JohnWrensby

4
मैं @JohnWrensby की टिप्पणी पर जोर देना चाहता हूं, Intellisense को कभी-कभी इन ThenInclude को संभालने में विशेष रूप से लंबा समय लग सकता है, यह नए उपयोगकर्ताओं के लिए काफी भ्रामक हो सकता है। मेरे पास ऐसे मामले भी थे जिनमें सरल शामिल लंबोदर अभिव्यक्ति को ठीक से संभाला नहीं गया था, जब तक कि आप इसे टाइप नहीं करते और इसे संकलित करते हैं, वीएस में दिखाए गए "त्रुटियों" की अनदेखी करते हुए।
Pac0

@ Pac0 आपने मेरा दिन बचाया। बाल वस्तुओं को देखने के लिए संघर्ष करना और नहीं कर सका।
बेंड्राम

28

मैंने एंटिटी फ्रेमवर्क 6 (.Net कोर शैली) के लिए थोड़ा सहायक बनाया, उप-संस्थाओं को एक अच्छे तरीके से शामिल करने के लिए।

यह अब NuGet पर है: Install-Package फिर InInclude.EF6

using System.Data.Entity;

var thenInclude = context.One.Include(x => x.Twoes)
    .ThenInclude(x=> x.Threes)
    .ThenInclude(x=> x.Fours)
    .ThenInclude(x=> x.Fives)
    .ThenInclude(x => x.Sixes)
    .Include(x=> x.Other)
    .ToList();

पैकेज GitHub पर उपलब्ध है


हाय, मैं क्रम में एक अपवाद है, कच्चा नहीं कर सकते IncludableQueryable <ObservableCollection> को IncludableQueryable <genericcollection>
user2475096

मैं पहले db का उपयोग कर रहा हूँ और मैंने tt फ़ाइल को अपनी सभी संस्थाओं के लिए ObservableCollections प्राप्त करने के लिए संशोधित किया है, किसी भी मदद का स्वागत है।
user2475096

2
@ lenny32 कुछ भी इस विस्तार के साथ पता होना चाहिए?
एरोन हुडोन

ध्यान दें कि यह आवश्यक नहीं है यदि आप जिस संपत्ति के लिए नेविगेट कर रहे हैं वह आपके द्वारा नेविगेट किए गए DbSet के साथ एक-से-एक है, और आप DbSet<One>().Include(x => x.Two.Three.Four.Five.Six)केवल एक कमी के साथ श्रृंखला कर सकते हैं जो आप कार्टेशियन उत्पाद और संभावित बढ़ते बैंडविड्थ की गणना कर रहे हैं।
जॉन ज़ब्रोस्की

23

MSDN पर अधिक EFCore उदाहरणों से पता चलता है कि आप कुछ जटिल चीजों के साथ Includeऔर कर सकते हैं ThenInclude

यह एक अच्छा उदाहरण है कि आप कितने जटिल हो सकते हैं (यह सब एक बयान है!):

viewModel.Instructors = await _context.Instructors

      .Include(i => i.OfficeAssignment)

      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Enrollments)
                .ThenInclude(i => i.Student)

      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Department)

      .AsNoTracking()
      .OrderBy(i => i.LastName)
      .ToListAsync();

देखें कि आप कैसे चेन कर सकते हैं Includeइसके बाद भी ThenIncludeऔर यह 'रीसेट' की तरह आपको शीर्ष स्तर इकाई (इंस्ट्रक्टर) के स्तर पर वापस करता है।

तुम भी एक ही 'पहले स्तर' संग्रह (CourseAssignments) कई बार अलग-अलग ThenIncludesआदेशों के बाद अलग- अलग बाल संस्थाओं को प्राप्त करने के लिए दोहरा सकते हैं ।

ध्यान दें कि आपकी वास्तविक क्वेरी को Includeया ThenIncludesश्रृंखला के अंत में टैग किया जाना चाहिए । निम्नलिखित काम नहीं करता है:

var query = _context.Instructors.AsQueryable();
query.Include(i => i.OfficeAssignment);

var first10Instructors = query.Take(10).ToArray();

यदि आप एक या दो से अधिक चीजों को शामिल कर रहे हैं, तो सुनिश्चित करें कि आप लॉगिंग सेट करने और अपने प्रश्नों को नियंत्रण से बाहर नहीं होने देंगे। यह देखना महत्वपूर्ण है कि यह वास्तव में कैसे काम करता है - और आप देखेंगे कि प्रत्येक अलग 'शामिल' आमतौर पर बड़े पैमाने पर जुड़ने वाले अनावश्यक डेटा से बचने के लिए एक नई क्वेरी है।

AsNoTracking यदि आप वास्तव में संस्थाओं को संपादित करने और फिर से शुरू करने का इरादा नहीं रखते हैं, तो चीजों को गति दे सकते हैं।


क्या आपके दोहराए बिना नामांकन और विभागों दोनों को प्राप्त करने का एक तरीका है। पाठ्यक्रम और पाठ्यक्रम के लिए शामिल हैं? (अब तक, ऐसा लगता है जैसे एपी के साथ गहराई तक जा सकता है। थेनइन्क्लूड, या वापस शीर्ष स्तर के साथ। इंकलेड, लेकिन समान स्तर पर रहने के लिए कुछ भी नहीं है?)
विलियम जॉकस

यदि आप आलसी-लोडिंग रहना चाहते हैं तो EF Core 2.1 blogs.msdn.microsoft.com/dotnet/2018/02/02/… के लिए तैयार रहें, लेकिन अगर आप बस उसी स्तर पर अधिक लोड करना चाहते हैं, तो मुझे लगता है कि यह डिज़ाइन द्वारा है। मुझे यकीन नहीं है कि आप क्या सोच रहे हैं - इसे करने के लिए बहुत अतिरिक्त की आवश्यकता नहीं है और यह डेटाबेस से वापस आने पर बहुत कम कर देता है। एक इकाई में सिर्फ एक या दो 'समान-स्तरीय' चीजें हो सकती हैं, लेकिन एक बड़ी परियोजना के लिए 50 भी हो सकती हैं, स्पष्ट रूप से आपके ऐप को बहुत तेज बनाता है।
सिमोन_विवर 23

यह "रीसेट" के स्तर को फिर से प्रारंभिक स्तर पर वापस शामिल करने की अवधारणा का एक अच्छा विवरण था। मुझे शामिल प्रणाली के उत्तराधिकार के चारों ओर अपना सिर लपेटने में मदद की। चीयर्स!
AFM- क्षितिज

22

मुझे भी कई शामिल करना था और तीसरे स्तर पर मुझे कई गुणों की आवश्यकता थी

(from e in context.JobCategorySet
                      where e.Id == id &&
                            e.AgencyId == agencyId
                      select e)
                      .Include(x => x.JobCategorySkillDetails)
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.DurationType))
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RuleType))
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RateType))
                      .FirstOrDefaultAsync();

यह किसी की मदद कर सकता है :)


1
क्या इसे दोहराए बिना किया जा सकता है.Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt......
मल्टीनेर्ड

अच्छी तरह से यह निर्भर करता है, आप कितने गहरे जाना चाहते हैं
dnxit

7

मुझे यह स्पष्ट रूप से बताएं कि आप स्ट्रिंग ओवरलोड का उपयोग कर सकते हैं ताकि संबंधित रिश्तों की बहुलता की परवाह किए बिना नेस्टेड स्तरों को शामिल किया जा सके, अगर आप स्ट्रिंग लीटर का उपयोग करने में कोई आपत्ति नहीं करते हैं:

query.Include("Collection.Property")

1
यह विधि मेरे लिए यह पता लगाने में मददगार थी कि वीबी में इसे कैसे कोडित किया जा सकता है, क्योंकि मैं गलगला के घंटों के बाद कहीं भी नहीं मिल सकता।
कोडर

यह मेरे लिए बहुत अच्छा काम करता है, मैं इसका भरपूर उपयोग करता हूँ !!! यहां तक ​​कि इसके साथ संयुक्त कार्य भी करता है। SlectMany स्टेटमेंट:query.SelectMany(x=>x.foos).Include("bar").Include("bar.docs")...
Ephie
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.