2014-10-28 5 views
28

के बाद मैं निम्नलिखित 2 वर्गों की है।प्राप्त इकाई नेविगेशन गुण डालने

अब मान लीजिए कि मैं एक इनाम इकाई बना सकते हैं और इस तरह से यह सम्मिलित करते हैं:

var reward = new Reward { CampaignId = 1 }; 
context.Set<Reward>().Add(reward); 
context.SaveChanges(); 

reward = context.Set<Reward>().SingleOrDefault(a => a.Id == reward.Id); 
//reward.Campaign is null 

मैं स्पष्ट रूप से तो FK बाधा खुश है ईद 1 के साथ एक अभियान है। इस सम्मिलन के बाद, मेरी इनाम इकाई में यह नया पहचान आईडी सेट है। अब समस्या यह है कि इनाम अभी भी केवल रिवार्ड इकाई है जिसे मैंने बनाया है। और इसके साथ, इनाम। अभियान संपत्ति शून्य है। ऐसा लगता है जैसे ईएफ मेमोरी में डाली गई इकाइयों को रख रहा है, और जब मैं एक करता हूं। .SingleOrDefault (a => a.Id == इनाम। आईडी) यह बस स्मृति में इकाई को लौटाता है, न कि एक नई प्रॉक्सी। यह शायद एक अच्छी बात है।

तो सवाल यह है कि: किसी ने डालने के बाद नेविगेशन गुणों को कैसे एक्सेस या लोड किया है या एक नई प्रॉक्सी प्राप्त की है जिसमें नेविगेशन गुण प्रॉक्सी के रूप में भी हैं।

क्या मैं शायद गलत तरीके से सम्मिलित कर रहा हूं?

+0

क्या आपके मानचित्रण कैसा दिखता है? – Maritim

+0

[संभावितता फ्रेमवर्क का संभावित डुप्लिकेट: मैंने विदेशी कुंजी सेट की है, SaveChanges नेविगेशन प्रॉपर्टी तक पहुंचें, लेकिन यह संबंधित इकाई लोड नहीं करता है। क्यों नहीं?] (Http://stackoverflow.com/questions/15552891/entity-framework-i-set-the-foreign-key-savechanges-then-access-the-navigation) – Colin

उत्तर

48

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

SaveChanges() जटिल गुणों को लोड करने के तरीके में कुछ भी नहीं करता है। अधिकतर, यदि आप नई ऑब्जेक्ट्स जोड़ रहे हैं तो यह आपकी प्राथमिक कुंजी प्रॉपर्टी सेट करने जा रहा है।

आपकी लाइन reward = context.Set<Reward>().SingleOrDefault(a => a.Id == reward.Id); Campaign लोड करने के तरीके में कुछ भी नहीं करती है क्योंकि आपका इनाम ऑब्जेक्ट संदर्भ से जुड़ा नहीं है। आपको स्पष्ट रूप से उस जटिल ऑब्जेक्ट को लोड करने या इसे संलग्न करने के लिए EF बताएं, फिर आलसी लोडिंग को अपने जादू को काम करने दें।

तो, आप context.SaveChanges(); के बाद आप लोड हो रहा है reward.Campaign के लिए तीन विकल्प हैं:

  1. Attach() संदर्भ ताकि Campaign lazily लोड किया जा सकता करने के लिए इनाम (जब तक पहुँचा लोड)

    context.Rewards.Attach(reward); 
    

    नोट: आप संदर्भ के दायरे में केवल reward.Campaign को आलसी लोड करने में सक्षम होंगे ताकि यदि आप नहीं जा रहे हैं संदर्भ जीवनकाल के भीतर किसी भी गुण का उपयोग करें, विकल्प 2 या 3 का उपयोग करें।

  2. मैन्युअल Load()Campaign संपत्ति

    context.Entry(reward).Reference(c => c.Campaign).Load(); 
    
  3. मैन्युअल Include()Campaign संपत्ति

    reward = context.Rewards.Include("Campaigns") 
        .SingleOrDefault(r => r.Id == reward.Id); 
    

    हालांकि, मैं सुझाव देंगे Load के बाद से आप पहले से ही में reward है याद।

अधिक जानकारी के लिए this msdn doc पर लोड हो रहा संबंधित ऑब्जेक्ट अनुभाग देखें।

+4

दूसरा विकल्प मेरे लिए सबसे अच्छा था भी। –

+2

पहला विकल्प मेरे लिए काम नहीं करता है –

9

जैसा कि आप reward ऑब्जेक्ट new Reward() के रूप में बना रहे हैं, ईएफ में प्रॉक्सी नहीं है। इसके बजाय, इस तरह DbSet.Create का उपयोग कर इसे बनाने के लिए:

var reward = context.Set<Reward>().Create(); 
reward.CampaignId = 5; 
context.SaveChanges(); 

अगला अपने DbSet के लिए देते:

var campaign = reward.Campaign; 
:

context.Rewards.Attach(reward); 

अंत में, आप अब संबंधित संस्थाओं प्राप्त करने के लिए आलसी लोड हो रहा है उपयोग कर सकते हैं

1

क्या आपने Include() का उपयोग करने का प्रयास किया था? कुछ ऐसा:

reward = context.Set<Reward>().Include("Campaigns").SingleOrDefault(a => a.Id == reward.Id); 
1

मेरे पास समस्या के आसपास एक सरल समाधान है। इनाम के लिए campaignid जोड़ने की

बजाय, अभियान वस्तु जोड़ने .. तो:

var _campaign = context.Campaign.First(c=>c.Id == 1);//how ever you get the '1' 
var reward = new Reward { Campaign = _campaign }; 
context.Set<Reward>().Add(reward); 
context.SaveChanges(); 

//reward.Campaign is not null 

इकाई की रूपरेखा यहाँ सभी बड़े कार्य करता है।

आप शायद सोच रहे हैं कि यह पूरे अभियान ऑब्जेक्ट को लोड करने का कचरा है, लेकिन यदि आप इसका उपयोग करने जा रहे हैं (ऐसा लगता है कि ऐसा लगता है, ऐसा लगता है) तो मुझे नहीं लगता कि क्यों नहीं। तुम भी include स्टेटमेंट का उपयोग कर सकते हैं जब ऊपर आप अभियान वस्तु से नेविगेशन गुण का उपयोग करने की जरूरत है अगर यह ला रहा है ...

var _campaign = context.Campaign.include(/*what ever you may require*/).First(c=>c.Id = 1); 
संबंधित मुद्दे