2012-01-09 13 views
5

मैंने आइटम (ईएफ) EntityCollection में आइटम जोड़ने के लिए एक विस्तार विधि लिखा है। मुझे एक दिलचस्प त्रुटि मिली, यह कहकर कि आईनेमेरेबल ("आइटम") का मेरा संग्रह संशोधित किया गया था, फोरच में पहले लूप के बाद। जब मैं वस्तुओं को वस्तुओं में बदल देता हूं .सूची() (नीचे दिए गए कोड में), यह ठीक काम करता है।सी # आईनेमेरेबल रहस्य का संशोधन, मेरे आईनेमरेबल को संशोधित करना क्या है?

मैं पूरी तरह से समझता हूं कि ToList() करना उन वस्तुओं की प्रतिलिपि तैयार करेगा जिन पर foreach तब काम करेगा।

जो मैं समझ नहीं पा रहा हूं वह है कि जब मैं इस पर एक foreach कर रहा हूँ INumerable संशोधित कर रहा है।

अद्यतन: किसी भी तरह, ऐसा लगता है कि आइटम वैरिएबल संग्रह चर के समान है?

अद्यतन 2: मुझे लगता है कि संग्रह और इकाई एफई के इकाई पर नज़र रखने से प्रभावित हो सकता है, लेकिन मैं अभी भी समझने में विफल क्यों

उपयोग:

ssp.ServiceAreas.ReplaceCollection(model.ServiceAreas);

यहाँ मेरी विस्तार विधि है:

public static void AddOrUpdate<TEntity>(this EntityCollection<TEntity> collection, IEnumerable<TEntity> items) 
     where TEntity : EntityObject, IProjectIdentity<int>, new() 
    { 
     foreach (var item in items.ToList()) 
      collection.AddOrUpdate(item); 
    } 

    public static void AddOrUpdate<TEntity>(this EntityCollection<TEntity> collection, TEntity item) 
     where TEntity : EntityObject, IProjectIdentity<int>, new() 
    { 
     if (item.ID > 0 && collection.Any(c => c.ID == item.ID)) 
      collection.Remove(collection.First(c => c.ID == item.ID)); 
     // For now, the Remove NEVER gets hit 

     collection.Add(item); 
    } 
+3

'निकालें' इसे संशोधित करता है, इसलिए जोड़ता है। – vcsjones

+2

@vcsjones हालांकि यह सच है, इस स्थिति में यह इतना आसान नहीं है। –

+1

क्या आपके मामले में 'आइटम == संग्रह' है? –

उत्तर

4
collection.Remove(collection.First(c => c.ID == item.ID)); 

आप जिस संग्रह को फिर से कर रहे हैं उसमें आप हटा रहे हैं।

+2

लेकिन पुनरावृत्ति एक अलग संग्रह (आइटम) – Erix

+0

के माध्यम से है, वास्तव में मैंने इसे ऊपर उठाया लेकिन कोशिश करने पर, इससे कोई समस्या नहीं आती है। –

+0

वास्तव में ईरिक्स, एडम, मैंने स्पष्टीकरण के लिए पोस्ट को अद्यतन किया है। – sebastiaan

0

शायद EntityCollection पसंद नहीं है जब कोई व्यक्ति इसके तत्वों को ले लेता है? इसलिए, जब आप collection में जोड़ते हैं, तो आइटम items से हटा दिया जाता है।

या यह हो सकता है कि items == collection

1

मैं निम्न नमूना कोड बनाया:

internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      var one = new List<string> {"Adam", "John"}; 

      var two = new List<string> {"Adam", "Houldsworth"}; 

      one.AddOrUpdate(two); 

      Console.Read(); 
     } 
    } 

    static class Extensions 
    { 
     public static void AddOrUpdate(this IList<string> collection, IEnumerable<string> items) 
     { 
      foreach (var item in items.ToList()) 
       collection.AddOrUpdate2(item); 
     } 

     public static void AddOrUpdate2(this IList<string> collection, string item) 
     { 
      if (collection.Any(c => c == item)) 
       collection.Remove(collection.First(c => c == item)); 

      collection.Add(item); 
     } 
    } 

यह काम करता है के रूप में आप उम्मीद करेंगे, कोई त्रुटि नहीं है। तो संक्षेप में, लाइनों में से कोई भी समस्याएं पैदा कर रहा है।

क्या मुद्दों का कारण होगा यदि आप पर ही सूची कहते हैं:

one.AddOrUpdate(one); 

तो मैं क्या देख सकते हैं, तो आप दोनों बहस के रूप में ही संग्रह के साथ इस विस्तार विधि बुला किया जाना चाहिए से।

यदि आप हैं, तो Remove या Add दोनों संग्रह को म्यूटेट करेंगे और इस अपवाद का कारण बनेंगे।

+0

धन्यवाद, लेकिन यह बिना और बिना काम करता है। टोस्टिस्ट() .. बस क्योंकि संग्रह और आइटम वास्तव में अलग-अलग वस्तु हैं। मुझे लगता है कि मेरा संग्रह ऑब्जेक्ट ईएफ की ट्रैकिंग तंत्र से प्रभावित हो सकता है, फिर से पोस्ट अपडेट करेगा। :-) – sebastiaan

+0

@sebastiaan हाँ मैंने देखा कि यह 'ToList' के बिना भी काम करता है, लेकिन मैं इसे आपके प्रदान किए गए कोड के समान रख रहा था ताकि यह पता चल सके कि समस्या कहां आ रही थी। –

0

यह हो सकता है कि पहला आइटम हमेशा एक नया आइटम होता है, और इस प्रकार डिफ़ॉल्ट रूप से आईडी कुछ प्रारंभिक मान पर सेट होती है। इसे तब संग्रह में जोड़ा जाएगा, जिससे EntityFramework को एक नई आईडी उत्पन्न हो और इसे पहले जोड़े गए आइटम पर असाइन किया जा सके।

यह हो सकता है कि EntityCollection सोचता है कि यह बदल गया है, क्योंकि यह आंतरिक रूप से कुछ और क्रमबद्ध करने के लिए आईडी का उपयोग करता है। और इस प्रकार foreach ऑपरेशन (जो शायद एक ही सूची का उपयोग कर रहा है) अपवाद फेंकता है। यही कारण है कि एडम होल्ड्सवर्थ द्वारा साबित परीक्षण-मामला इस मुद्दे को नहीं देता है!

0
EntityCollection<Customer> customers = new EntityCollection<Customer>(); 
Customer newCustomer = new Customer() {ID = 0}; 
customers.Add(newCustomer); 
customers.AddOrUpdate(customers); 
संबंधित मुद्दे