2016-01-06 14 views
6

मैं गुण के रूप में दो वस्तुओं (User, PrimaryNode) के साथ एक वस्तु है, दोनों संभावित अशक्त हो सकता है, नीचे देखें Item ऑब्जेक्ट और जंजीर का उपयोग करने में PrimaryNode और User ऑब्जेक्ट्स इसके भीतर ऑब्जेक्ट्स को पॉप्युलेट करना शामिल है।इकाई की रूपरेखा ObjectQuery.Include()

जब पहली श्रृंखलित शामिल एक अशक्त वस्तु तो बातिल के रूप में पूरी वस्तु रिटर्न, उदाहरण के लिए:

using (var db = new MyContext()) 
{ 
    var item = db.Items.Include(i => i.User).Include(n => n.PrimaryNode).FirstOrDefault(i => i.ItemId == id); 
} 

ऊपर के उदाहरण में i.User रिक्त है तो item चर अशक्त है। सब-ऑब्जेक्ट्स दोनों को इस तरह से पॉप्युलेट करने का सबसे अच्छा तरीका क्या है कि यदि उप-ऑब्जेक्ट शून्य है तो मूल ऑब्जेक्ट और अन्य उप-ऑब्जेक्ट अभी भी पॉप्युलेट हो जाएगा?

+3

'प्राथमिक नोड' और 'उपयोगकर्ता' वर्चुअल बनाएं और उन्हें 'आइटम'' के रूप में वैकल्पिक रूप से मानचित्र बनाएं? –

+0

मैं @octavioccl द्वारा दिए गए बयान से सहमत हूं - आपकी क्वेरी में कुछ भी गलत नहीं है। मेरे परीक्षण में, वह क्वेरी नोड ऑब्जेक्ट को पॉप्युलेट करेगी, भले ही आइटम से कोई उपयोगकर्ता ऑब्जेक्ट न हो। –

+0

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

उत्तर

1

मुझे नहीं लगता कि आपकी समस्या का Include कॉल की वजह से है। documentation साथ अनुसार:

इस विस्तार विधि, IQueryable स्रोत ऑब्जेक्ट की Include(String) प्रणाली को बुलाती है, तो इस तरह के एक विधि मौजूद है। यदि स्रोत IQueryable में कोई मिलान विधि नहीं है, तो यह विधि कुछ भी नहीं है।

दूसरे शब्दों में करने के लिए अनुवाद किया जा रहा है:

var item = db.Items.Include("User").Include("PrimaryNode").FirstOrDefault(i => i.ItemId == id); 

मेरा प्रश्न है, क्या आप वाकई अपने DB में कि आईडी ठीक से Users में मौजूदा पंक्तियों के साथ संबंधित के साथ एक Item और PrimaryNodes टेबल है ?। जब आप अंत में Include विधि को कॉल करने के लिए अनुवादित करने जा रहे हैं, तो यदि आपके रिश्ते का एफके संदर्भित पीके से मेल नहीं खाता है, तो आपकी क्वेरी को आप जो उम्मीद कर रहे हैं उसे वापस नहीं करना चाहिए।

फिर भी, अगर आप संबंधित गुणों लोड करने के लिए एक और संस्करण की कोशिश करना चाहते तुम Explicit Loading उपयोग कर सकते हैं:

var item = db.Items.FirstOrDefault(i => i.ItemId == id); 
context.Entry(item).Reference(p => p.PrimaryNode).Load(); 
context.Entry(item).Reference(p => p.User).Load(); 
+0

यह भी ध्यान रखें कि आप Lambdas का उपयोग कर सकते हैं। 'db.Items.Include (item => item.User)'। मैं इसे ऊपर लाता हूं क्योंकि यह थोड़ा और रिफैक्टर अनुकूल है। – Cameron

+0

क्या मैं यह सोचने में सही हूं कि स्पष्ट लोडिंग उदाहरण के परिणामस्वरूप डेटाबेस में तीन कॉल होंगे? जबकि जंजीर शामिल का उपयोग डेटाबेस के साथ जुड़ने के साथ एक एकल कॉल बनाता है। –

1

मुझे लगता है कि अगर आप आलसी लोडिंग को अपनी स्थिति में इस्तेमाल करते हैं तो यह बेहतर होगा।

public class Item 
{ 
    [Key] 
    public int ItemId { get; set; } 
    public string ItemName { get; set; } 
    public virtual Node PrimaryNode { get; set; } 
    public virtual User User { get; set; } 
} 

और फिर:: बस User और PrimaryNode आभासी बनाने

var db = new MyContext(); 
var item = db.Items.FirstOrDefault(i => i.ItemId == id); 
+0

सुझाव के लिए धन्यवाद। यह मेरे परिदृश्य में काम नहीं करेगा, अगर मैं आलसी लोडिंग को सही ढंग से समझता हूं, तो मैं एक डिस्कनेक्ट परिदृश्य में काम कर रहा हूं। मुझे डीबी से डेटा मिल रहा है और इसे प्रदर्शन के लिए एक वेब पेज पर लौट रहा है। –

+0

@ एंडीई ... आपका स्वागत है। आलसी लोडिंग वह प्रक्रिया है जिसके द्वारा पहली बार डेटाबेस से इकाइयों या संग्रहों को स्वचालित रूप से लोड किया जाता है, जब पहली बार इकाई/संस्थाओं का संदर्भ देने वाली संपत्ति का उपयोग किया जाता है। –

0

दूसरों के रूप में उल्लेख किया है, मुझे लगता है कि आपकी समस्या का कारण भी शामिल करने के लिए नहीं है। हालांकि, मुझे लगता है कि निम्न विधि का मूल्य है। यह कार्यात्मक रूप से बराबर है जो आप पहले से ही जंजीर के साथ कर रहे हैं, लेकिन मुझे लगता है कि इसमें उपयोगकर्ता को स्पष्ट कोड के इरादे को शामिल करने सहित कई लाभ हैं।

विस्तार के तरीकों में रखा जा सकता है शामिल है:

using System.Data.Entity; 
using System.Linq; 

namespace Stackoverflow 
{ 
    public static class EntityExtensions 
    { 
     public static IQueryable<Item> IncludePrimaryNode(this IQueryable<Item> query) 
     { 
      // eager loading if this extension method is used 
      return query.Include(item => item.PrimaryNode); 
     } 

     public static IQueryable<Item> IncludeUser(this IQueryable<Item> query) 
     { 
      // eager loading if this extension method is used 
      return query.Include(item => item.User); 
     } 
    } 
} 

उसके बाद, आप एक्सटेंशन के रूप में इस का उपयोग कर सकते हैं:

using (var db = new MyContext()) 
{ 
    var itemQuery = db.Items.IncludeUser(); 

    itemQuery = itemQuery.IncludePrimaryNode(); 

    var item = itemQuery.FirstOrDefault(i => i.Id == 1); 
} 

यह सिर्फ एक ही बात करने का एक और तरीका है, लेकिन मुझे पसंद है यह स्पष्टता कोड में जोड़ता है।

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