XMLserializer,Entity Framework:无法序列化 ICollection 类型的成员,有关详细信息,请参阅内部异常

XMLserializer, Entity Framework : Cannot serialize member of type ICollection see inner exception for more details

我想将 XML 元素映射到我的数据库 table(使用 Entity Framework):

var xmlSerializer = new XmlSerializer(typeof(Participant), new XmlRootAttribute("participant"));
var participant = (Participant)xmlSerializer.Deserialize(new StringReader(content));

我有参与者 table,我可以通过

访问它
[XmlRoot("participant", Namespace = "")]
    public partial class Participant
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",     "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Participant()
        {
            this.GroupParticipant = new HashSet<GroupParticipant>();
            this.ParticipantAddress = new HashSet<ParticipantAddress>();
            this.ParticipantPublisher = new HashSet<ParticipantPublisher>();
            this.ParticipantJob = new HashSet<ParticipantJob>();
            this.ParticipantProvider = new HashSet<ParticipantProvider>();
        }
        [XmlElement("firstName")]
        public string FirstName { get; set; }

        [XmlElement("lastName")]
        public string LastName { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        //[XmlElement("address")]
        //[XmlElement("address")]
        //[XmlArray("HashSet<ParticipantAddress>"), XmlElement("address")]
        //[XmlArrayItem("ICollection<ParticipantAddress>")]
        //[XmlAttribute(DataType = "ICollection<ParticipantAddress>",  AttributeName = "address")]

[XmlElement("address", typeof(List<ParticipantAddress>))]
        public virtual ICollection<ParticipantAddress> ParticipantAddress { get; set; }
}

ParticipantAddress 是 ICollection:

[Serializable]
    [XmlInclude(typeof(HashSet<ParticipantAddress>))]
    public partial class ParticipantAddress
    {
        public int ParticipantAddressId { get; set; }
        public int ParticipantId { get; set; }

        [XmlElement("city")]
        public string City { get; set; }

        [XmlElement("state")]
        public string State { get; set; }

        [XmlElement("zipCode")]
        public string ZipCode { get; set; }

        public virtual Participant Participant { get; set; }
    }

例外说:

{"There was an error reflecting type 'x.Participant'."}

我内心的异常说:

{"Cannot serialize member 'xParticipant.ParticipantAddress' of type 'System.Collections.Generic.ICollection`1[[x.ParticipantAddress, APS.Data.BatchInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]', see inner exception for more details."}

我正在通过 streamReader 阅读 XML。

我试过了

是否有任何其他方法可以解决此问题或与我的问题相关的任何示例或我需要在代码中实施的任何更改?

您遇到此问题是因为 virtual 属性。您尝试序列化一个 class,它引用了另一个 class,它引用了第一个 class,这...无限循环。

如果你想序列化一个实体,你能做的最好的事情就是使用 DTO class,这是一个 class 只用于导出你的数据。在这些 classes 中,您不能拥有虚拟属性,但您可以做的是包含 ParticipantAddress 的 DTO 对象。

如果不需要序列化到 XML,您可以尝试的另一件事是使用 Newtonsoft.Json 包来序列化实体。该包有一些选项来处理导航属性。

ICollection 不可序列化。
- 你可以使用DTO。
- 您可以更改集合类型(即使用 List<>)并使用 XML 序列化属性避免循环引用 and/or 禁用延迟加载(即使用 Include 方法使用急切加载)或风险是您序列化整个数据库。

我创建了一个区域并将 ICollection<> 更改为 List<> 因为

ICollection is an interface and interfaces are not serializable.

但是 List<> 是一个 class 并且这个 class 实现了以下所有接口: IList、ICollection、IList、ICollection、IReadOnlyList、IReadOnlyCollection、IEnumerable、IEnumerable。

我保留了 Icollection 和 List,并将 [XmlIgnore] 放在 ICollection 上。

    [XmlRoot("participant", Namespace = "")]
    public partial class Participant
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Participant()
        {
            this.GroupParticipantList = new List<GroupParticipant>();
            this.ParticipantAddressList = new List<ParticipantAddress>();
            this.ParticipantPublisherList = new List<ParticipantPublisher>();
            this.ParticipantJobList = new List<ParticipantJob>();
            this.ParticipantProviderList = new List<ParticipantProvider>();
        }

        [XmlElement("firstName")]
        public string FirstName { get; set; }

        [XmlElement("lastName")]
        public string LastName { get; set; }

        [XmlIgnore]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<ParticipantAddress> ParticipantAddress { get; set; }

        #region Custom properties

        [XmlElement("address")]
        public virtual List<ParticipantAddress> ParticipantAddressList { get; set; }

        #endregion
    }

但是使用这个选项我有另一个问题:如果我在我的SQL数据库中做任何单一的改变并且如果我从数据库更新模型,那么我像这段代码中的所有 XML 句子一样丢失手动实现的代码。

我在下面的文章中回答了这个问题,将 [System.Xml.Serialization.XmlIgnore] 添加到 entity.tt 模板

Prevent Property from being serialized

我在使用 EF 实现 Web 服务时遇到了类似的问题,但无法序列化 ICollection<> 对象。 希望对您有所帮助。

public class User
{
    public User()
    {
        sessions = new HashSet<Session>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    [XmlIgnore]
    [IgnoreDataMember]
    public virtual ICollection<Session> sessions { get; set; }
}


public class Session
{
    public int Id { get; set; }
    public Datetime start_dtime{ get; set; }
    public Datetime end_dtime{ get; set; }

    public virtual User user{ get; set; }
}