如何在使用实体框架</t>时序列化ICollection <t>类型的属性

时间:2011-09-21 15:42:39

标签: entity-framework serialization deserialization

我有一个如下所示的课程

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 ICollection<Question> Questions { get; set; }
        public virtual ICollection<SurveyResponse> SurveyResponses { get; set; }
    }

以上代码给出了以下异常

  

无法序列化类型的成员'SurveyGenerator.Survey.Questions'   “了System.Collections.Generic.ICollection

当我将ICollection转换为List时,它正确序列化

由于它是实体框架的POCO,我无法将ICollection转换为List

5 个答案:

答案 0 :(得分:2)

从类的外观来看,ICollection属性是否定义了外键关系?如果是这样,您就不希望公开展示这些集合。

例如:如果您正在遵循开发实体框架模型的最佳实践指南,那么您将有一个名为“问题”的单独类,它将您的两个类连接在一起,可能如下所示:

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; }
}

如果是这种情况,你很可能绕圈子调用问题 - &gt;调查 - &gt; ICollection - &gt;问题

我有类似的事件使用EF,MVC3来实现REST服务,并且无法序列化ICollection&lt;&gt;对象然后意识到我不需要,因为无论如何我将单独调用该对象。

为您的目的更新的课程将如下所示:

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; }
}

我希望这会帮助你。

答案 1 :(得分:1)

ICollection&lt; T&gt; 更改为列表&lt; T&gt;

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; }
}

答案 2 :(得分:1)

如果您不介意添加对程序集System.Runtime.Serialization的引用,则可以使用此代码,该代码将使用ICollection序列化对象,而无需更改对象的实现。下面的代码输出到字符串。您可以根据需要使用流。

    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());
        }
    }

答案 3 :(得分:0)

我使用了Matthew Merryfull解决方案并且有效。

由于我每次更新模型时都使用EF设计器进行实体生成,因此我会松开手动更改。我不得不改变用于生成模型的* .tt。我编辑了几行:

   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));
}

如果您遇到序列化问题http://geekswithblogs.net/danemorgridge/archive/2010/05/04/entity-framework-4-wcf-amp-lazy-loading-tip.aspx

,请查看此文章

答案 4 :(得分:0)

对我来说,问题是没有默认构造函数。例: 列出MyVar; // MyClass需要一个公共构造函数