6

का उपयोग कर ईएफ 4.1 इकाइयों को सीरियलाइज करना मैं एमवीसी 3, रेजर व्यू इंजन, वर्क यूनिट ऑफ वर्क के साथ रिपोजिटरी पैटर्न का उपयोग कर एक एप्लीकेशन बना रहा हूं और अपना डेटा मॉडल परिभाषित करने के लिए पहले ईएफ 4.1 कोड का उपयोग कर रहा हूं।JSON.Net

यहां कुछ पृष्ठभूमि है (यदि आप चाहें तो उस पर चमक लें)।

एप्लिकेशन स्वयं ही इंट्रानेट 'मेनू' है।

2 मुख्य संस्थाओं MenuItem और विभाग जिनमें से कर रहे हैं:

  • MenuItem कई विभागों हो सकता है
  • विभागों कई MenuItems
  • हो सकता है
  • MenuItem एक माता पिता
के रूप में एक MenuItem हो सकता है

इस प्रकार मैंने अपनी संस्थाओं को परिभाषित किया है

public class MenuItem 
{ 
    public int MenuItemId { get; set; } 
    public string Name { get; set; } 
    public string Url { get; set; } 
    public virtual ICollection<Department> Departments { get; set; } 
    public int? ParentId { get; set; } 
    public virtual MenuItem ParentMenuItem { get; set; } 
} 

public class Department 
{ 
    public int DepartmentId { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<MenuItem> MenuItems { get; set; } 
} 

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

जो मुद्दा मैं कर रहा हूं वह जेएसओएन के माध्यम से दृश्य में मेनूइटम को पास कर रहा है। केंद्रीय मुद्दे यह है कि मेरे पास मेरी इकाइयों के बीच एक परिपत्र संदर्भ है जो JSON पार्सर में निर्मित नहीं हो सकता है और मेरे पास आलसी लोडिंग और प्रॉक्सी पीढ़ी अभी भी सक्षम है।

मैं अपने JSON Serializer के रूप में Nuget से JSON.net लाइब्रेरी का उपयोग कर रहा हूं क्योंकि यह परिपत्र संदर्भ समस्या के चारों ओर एक अच्छा तरीका प्रतीत होता है। अब मैं अनिश्चित हूं कि प्रॉक्सी पीढ़ी के मुद्दे को कैसे ठीक किया जाए। वर्तमान में धारावाहिक The RelationshipManager object could not be serialized. This type of object cannot be serialized when the RelationshipManager belongs to an entity object that does not implement IEntityWithRelationships.

क्या कोई इस से मेरी सहायता कर सकता है? अगर मैं प्रॉक्सी पीढ़ी को बंद कर देता हूं, तो मुझे मेनू मेनू के सभी बच्चों को लोड करने का समय लगता है, इसलिए मैं इसे छोड़ने के लिए उत्सुक हूं। मैंने एक उचित राशि पढ़ी है और कई अलग-अलग उत्तरों के रूप में प्रतीत होता है जिसमें संस्थाओं को किसी अन्य वस्तु में प्रक्षेपित करना और उस आदि को क्रमबद्ध करना आदि आदर्श रूप से RelonManager ऑब्जेक्ट को अनदेखा करने के लिए JSON.net को कॉन्फ़िगर करने का कोई तरीका होगा?

अद्यतन

यहाँ मैं एक JSON.Net के लिए कस्टम ContractResolver serializer के रूप में इस्तेमाल किया है। ऐसा लगता है कि मेरी समस्या हल हो गई है।

public class ContractResolver : DefaultContractResolver 
{ 
    private static readonly IEnumerable<Type> Types = GetEntityTypes(); 
    private static IEnumerable<Type> GetEntityTypes() 
    { 
     var assembly = Assembly.GetAssembly(typeof (IEntity)); 
     var types = assembly.GetTypes().Where(t => String.Equals(t.Namespace, "Namespace", StringComparison.Ordinal)); 
     return types; 
    } 

    protected override List<MemberInfo> GetSerializableMembers(Type objectType) 
    { 
     if (!AllowType(objectType)) 
      return new List<MemberInfo>(); 

     var members = base.GetSerializableMembers(objectType); 
     members.RemoveAll(memberInfo => (IsMemberEntityWrapper(memberInfo))); 
     return members; 
    } 

    private static bool AllowType(Type objectType) 
    { 
     return Types.Contains(objectType) || Types.Contains(objectType.BaseType); 
    } 

    private static bool IsMemberEntityWrapper(MemberInfo memberInfo) 
    { 
     return memberInfo.Name == "_entityWrapper"; 
    } 
} 

IEntity एक इंटरफेस अपने सभी कोड पहले इकाई वस्तुओं को लागू है।

उत्तर

0

ठीक है, आप शक्तिशाली क्रमबद्धता एपीआई जो संदर्भ और साथ ही सभी सदस्यों को धारावाहिक इस्तेमाल किया और अब आप शिकायत है कि यह सभी सदस्यों :) serializes

मैं इसे परीक्षण नहीं किया था, लेकिन मेरा मानना ​​है कि यह आप के पास लाएगा उपाय।

JSON.NET काफी शक्तिशाली टूल है और इसे आपको इस व्यवहार से बचने के लिए एक्स्टेंसिबिलिटी पॉइंट प्रदान करना चाहिए लेकिन आपको इसे स्वयं कोड करना होगा। आपको कस्टम DataContractResolver की आवश्यकता होगी जहां आप परिभाषित करते हैं कि किन सदस्यों को क्रमबद्ध किया जाना चाहिए। Here NHibernate के लिए एक समान उदाहरण है।

आप कुछ तर्क लागू कर सकते हैं जो गतिशील प्रॉक्सी के मूल वर्ग में केवल सदस्य ही उपस्थित होंगे। मुझे आशा है कि यह आलसी लोडिंग को तोड़ नहीं देगा।यह सत्यापित करने के मौजूदा इकाई प्रॉक्सी है आप सभी ज्ञात प्रॉक्सी प्रकार प्राप्त करने के लिए इस कोड का उपयोग कर सकते हैं:

IEnumerable<Type> types = ((IObjectContextAdapter)dbContext).ObjectContext.GetKnownProxyTypes(); 
+0

धन्यवाद Ladislav। आपके संदर्भित ब्लॉग पोस्ट से मैं एक कस्टम 'कॉन्ट्रैक्ट रिसेल्वर' लिखने में सक्षम था, जिसमें निर्दिष्ट करने के लिए कौन से सदस्य, और अधिक विशेष रूप से किस प्रकार के ऑब्जेक्ट प्रकार निकलते हैं। कुछ मामलों में, धारावाहिक होने के माध्यम से एक ढांचा वस्तु पारित की जा रही थी इसलिए मुझे ऑब्जेक्ट प्रकार की जांच करनी पड़ी। मैं अपने प्रश्न को मेरे द्वारा उपयोग किए गए कोड के साथ अपडेट कर दूंगा। इस पर टिप्पणी करने के लिए स्वतंत्र महसूस करें :) –

2

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

class ContractResolver : DefaultContractResolver 
{ 
     protected override List<System.Reflection.MemberInfo> GetSerializableMembers(Type objectType) 
     { 
      if (objectType.Namespace.StartsWith("System.Data.Entity.Dynamic")) 
      { 
       return base.GetSerializableMembers(objectType.BaseType); 
      } 

      return base.GetSerializableMembers(objectType); 
     } 
} 

यह काम करता है क्योंकि एफई कोड पहले कक्षाएं POCO वर्ग कि आप वास्तव में चाहते हैं धारावाहिक से विरासत है, इसलिए यदि हम पहचान सकते हैं जब हम देख रहे हैं एक ईएफ जेनरेट क्लास (नेमस्पेस की जांच करके) हम बेस क्लास से गुणों का उपयोग करके क्रमबद्ध करने में सक्षम हैं, और इसलिए केवल पीओसीओ गुणों को क्रमबद्ध करें जो हम वास्तव में पहले स्थान पर थे।

+1

मैंने पाया कि आपको ऑब्जेक्ट टाइप करने की आवश्यकता है! = Null && objectType.Namespace! = Null –

+0

@ टोनीओहगन बिल्कुल - आपको हमेशा पैरामीटर को निरस्त करना चाहिए। मैंने उन्हें यहां अल्पसंख्यक के लिए छोड़ दिया –