2015-11-24 11 views
7

मैं एक datagrid एक संग्रह एक BindingSource के माध्यम से करने के लिए बाध्य है कि है:इकाई की रूपरेखा ताज़ा डाटा

  bsProducts.DataSource = cc.Products.Local.ToBindingList(); 

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

इकाई ताज़ा करने के लिए मैं निम्नलिखित कोड का उपयोग कर रहा:

 await cc.Entry<Product>(product).ReloadAsync(); 

लेकिन वह किसी भी संबंधित संस्थाओं है कि उत्पाद इकाई के लिए बाध्य कर रहे हैं लोड नहीं होगा। मैंने बाद में बाध्यकारी स्रोत अपडेट करने के लिए पुनः प्रयास किया है लेकिन कोई भाग्य नहीं है।

+0

पुनः लोड करने के बाद, क्या आप फिर से बांधते हैं? – MichaelMao

+0

हां, लेकिन ReloadAsync के बाद संपत्ति में अभी भी संबंधित संबंधित संबंधित संस्थाओं में से कोई भी नहीं है, केवल पुराने हैं। मैंने मैन्युअल रूप से संबंधित इकाइयों को लोड करके और उन्हें सूची <> के रूप में असाइन करके एक समाधान किया है। – Martin

+0

अद्यतन –

उत्तर

2

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

इस विधि आप बस फोन कर सकते हैं का उपयोग करना ...

cc.Visit(product, e => cc.Entry(e).Reload()); 

... और आप देखेंगे कि product और सभी पालन वस्तुओं पुनः लोड कर रहे हैं।

public static class DbContextExtensions 
{ 
    public static void Visit(this DbContext context, object entity, Action<object> action) 
    { 
     Action<object, DbContext, HashSet<object>, Action<object>> visitFunction = null; // Initialize first to enable recursive call. 
     visitFunction = (ent, contxt, hashset, act) => 
      { 
       if (ent != null && !hashset.Contains(ent)) 
       { 
        hashset.Add(ent); 
        act(ent); 
        var entry = contxt.Entry(ent); 
        if (entry != null) 
        { 
         foreach (var np in contxt.GetNavigationProperies(ent.GetType())) 
         { 
          if (np.ToEndMember.RelationshipMultiplicity < RelationshipMultiplicity.Many) 
          { 
           var reference = entry.Reference(np.Name); 
           if (reference.IsLoaded) 
           { 
            visitFunction(reference.CurrentValue, contxt, hashset, action); 
           } 
          } 
          else 
          { 
           var collection = entry.Collection(np.Name); 
           if (collection.IsLoaded) 
           { 
            var sequence = collection.CurrentValue as IEnumerable; 
            if (sequence != null) 
            { 
             foreach (var child in sequence) 
             { 
              visitFunction(child, contxt, hashset, action); 
             } 
            } 
           } 
          } 
         } 
        } 
       } 
      }; 
     visitFunction(entity, context, new HashSet<object>(), action); 
    } 

    // Get navigation properties of an entity type. 
    public static IEnumerable<NavigationProperty> GetNavigationProperies(this DbContext context, Type type) 
    { 
     var oc = ((IObjectContextAdapter)context).ObjectContext; 
     var objectType = ObjectContext.GetObjectType(type); // Works with proxies and original types. 

     var entityType = oc.MetadataWorkspace.GetItems(DataSpace.OSpace).OfType<EntityType>() 
          .FirstOrDefault(et => et.Name == objectType .Name); 
     return entityType != null 
      ? entityType.NavigationProperties 
      : Enumerable.Empty<NavigationProperty>(); 
    } 
} 

यह एक पुनरावर्ती क्रिया एक विस्तार विधि में लिपटे है:

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

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

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

2

आप ApplyCurrentValues ​​की कोशिश की है() फ़ंक्शन, यह आपके संदर्भ की तरह दिखता है बस isin't नवीनतम मूल्यों ले, आप पहले से ही एक ताज़ा समारोह है कि करता है बनाया है:

bsProducts.DataSource = cc.Products.Local.ToBindingList(); 
bsProducts.DataBind(); 
फिर

आप लागू करना चाहते migth ऐसा करने से पहले मौजूदा मूल्य।

क्षमा करें अगर इसे हल नहीं किया गया है, तो मुझे एक ही समस्या थी और इसे हल किया गया, शायद आपका मामला न हो।

https://msdn.microsoft.com/en-us/library/dd487246(v=vs.110).aspx

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