How to Serialize property of type ICollection while using Entity Framework

后端 未结 5 808
离开以前
离开以前 2021-01-04 10:14

I have a class as shown below

public class Survey
    {
        public Survey()
        {
            SurveyResponses=new List();
              


        
相关标签:
5条回答
  • 2021-01-04 10:24

    Change the ICollection<T> to a List<T>

    public class Survey
    {
        public Survey()
        {
            SurveyResponses=new List<SurveyResponse>();
        }
    
        [Key]
        public Guid SurveyId { get; set; }
        public string SurveyName { get; set; }
        public string SurveyDescription { get; set; }
        public virtual List<Question> Questions { get; set; }
        public virtual List<SurveyResponse> SurveyResponses { get; set; }
    }
    
    0 讨论(0)
  • 2021-01-04 10:28

    I used Matthew Merryfull solution and it works.

    Since I am using EF designer for entity generation each time I update my models I would loose manual changes. I had to change *.tt which is used for generation of models. I edited few lines:

       public string NavigationProperty(NavigationProperty navigationProperty)
    {
    var enbleWebService = string.Empty;
    if(navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ){
    enbleWebService = string.Format("[XmlIgnore]{0}[IgnoreDataMember]{0}", Environment.NewLine);
    }
        var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
        return string.Format(
            CultureInfo.InvariantCulture,
            "{5} {0} {1} {2} {{ {3}get; {4}set; }}",
            AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
            navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
            _code.Escape(navigationProperty),
            _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
            _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)),
             _code.Escape(enbleWebService));
    }
    
     public string NavigationProperty(NavigationProperty navigationProperty)
    {
    var enbleWebService = string.Empty;
    if(navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ){
        enbleWebService = string.Format("[XmlIgnore]{0}[IgnoreDataMember]{0}", Environment.NewLine);
    }
        var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
        return string.Format(
            CultureInfo.InvariantCulture,
            "{5} {0} {1} {2} {{ {3}get; {4}set; }}",
            AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
            navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
            _code.Escape(navigationProperty),
            _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
            _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)),
             _code.Escape(enbleWebService));
    }
    

    Also check this article in case you run into problem with serialization http://geekswithblogs.net/danemorgridge/archive/2010/05/04/entity-framework-4-wcf-amp-lazy-loading-tip.aspx

    0 讨论(0)
  • 2021-01-04 10:30

    For me the issue was not having a default constructor. Example: List MyVar; // MyClass needs a public constructor

    0 讨论(0)
  • 2021-01-04 10:35

    From the looks of your class the ICollection properties are defining foreign key relationships? If so, you wouldn't want to be publicly exposing the collections.

    For example: If you are following the best practices guide for developing Entity Framework models, then you would have a separate class called "Question" which would wire up your two class together which might look like the following:

    public class Question
    {
        [Key]
        public int Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
    
        public virtual Survey Survey { get; set; }
    }
    

    If this was the case, you could quite possibly go round in circles calling the Question -> Survey -> ICollection -> Question

    I had a similar incident using EF, MVC3 to implement a REST service and couldn't serialize the ICollection<> object then realised I didn't need to as I would be calling the object separately anyway.

    The updated class for your purposes would look like this:

    public class Survey
    {
        public Survey()
        {
            SurveyResponses=new List<SurveyResponse>();
        }
    
        [Key]
        public Guid SurveyId { get; set; }
        public string SurveyName { get; set; }
        public string SurveyDescription { get; set; }
    
        [XmlIgnore]
        [IgnoreDataMember]
        public virtual ICollection<Question> Questions { get; set; }
    
        [XmlIgnore]
        [IgnoreDataMember]
        public virtual ICollection<SurveyResponse> SurveyResponses { get; set; }
    }
    

    I hopes this helps you out.

    0 讨论(0)
  • 2021-01-04 10:37

    If you don't mind adding a reference to the assembly System.Runtime.Serialization, you can utilize this code which will serialize an object with ICollection without needing to change the object's implementation. The code below is outputting to string. You can use the stream however you'd like.

        private string ConvertClassToXMLString<T>(T classObject)
        {
            using (var stream = new MemoryStream())
            {
                var serializer = new DataContractSerializer(classObject.GetType());
                serializer.WriteObject(stream, classObject);
    
                return Encoding.UTF8.GetString(stream.ToArray());
            }
        }
    
    0 讨论(0)
提交回复
热议问题