映射和序列化双向关联

风暴

我认为,这将是一个小问题,可以立即找到答案,但是互联网以某种方式证明了我的假设是错误的。

我有一个包含几个实体的模型,这些实体之间具有所有可能的关联(1到1、1到很多,很多到很多,聚合,组成等)。为了简单起见,让我们以这个例子为例。我们有一个Person类和一个Car类。一个人可以拥有多辆汽车,但是一辆汽车只能属于一个人(因此,一对多关系)。现在,在Person中创建一个List / ArrayList来跟踪他/她的汽车将非常简单。但是,我也想跟踪车主。因此,这些类如下所示:

[Serializable]
public class Person
{
    [XmlElement]
    public List<Car> Cars { get; set; }

    [XmlAttribute]
    public string Name { get; set; }

    public Person()
    {
        Cars = new List<Car>();
    }
}

[Serializable]
public class Car
{
    [XmlElement]
    public Person Owner { get; set; }

    [XmlAttribute]
    public string Type { get; set; }

    public Car()
    {
    }
}

但是,我相信,这种结构会在Xml文件中引起无限循环,如下所示:

<Person name="John Doe">
  <Cars>
    <Car type="Ford">
      <Owner>
        <Person name="John Doe">
          <Cars>
            <Car type="Ford">
              <Owner>
                <Person name="John Doe">
      ... etc.

我什至尝试了它,并且在序列化过程中得到了“您需要将XmlChoiceIdentifierAttribute添加到'Owner'成员。” 例外。

因此,我有几个问题:1.有没有办法防止序列化循环?2.如果不是,是否必须为每个类编写自己的序列化器?3.此映射可以吗?还是有其他/更好的方法?我考虑过一个中央的“映射器”类,该类将基于ID返回所需的对象...但是同样,这可以通过SQL来完成。而且我想避免使用SQL(因为使应用程序保持轻量化)。

马克·格雷韦尔

XmlSerializer是树序列化器,而不是图形序列化器。最好的选择是避免在序列化过程中向后导航,例如,通过执行以下操作:

[XmlIgnore]
public Person Owner { get; set; }

(“父母”和“所有者”几乎总是向后导航)

不幸的是,XmlSerializer不支持序列化后的回调,否则可以添加如下内容:

[WhateverOnAfterDeserialized]
public void OnAfterDeserialized(...) {
    foreach(var car in cars) car.Owner = this;
}

其他一些序列化程序确实支持序列化回调,但是通过这种标记,那些其他序列化程序也可能也支持全图序列化。例如,DataContractSerializer可以同时支持回调和完整图形,但对xml的控制要少得多。

另一种选择是拥有一个自定义集合类型,该类型在您添加/删除时维护父属性。例如:

public class Person
{
    private readonly CarCollection cars;
    public Person() {
        cars = new CarCollection(this);
    }
    [XmlElement]
    public CarCollection Cars { get { return cars; } } 

    ...
}

与(中CarCollection):

// add code...
innerList.Add(value);
value.Parent = parent; // this is the field stored in the constructor

就个人而言,我认为这可能是过大的。

另一个选择是简单地添加一个反序列化后调用的修复方法,该方法可以执行所有必要的操作(并向下层叠):

public void FixupAfterDeserializer() {
    foreach(var car in cars) car.Parent = this;
}

请注意,您将必须手动调用它。

最后,请注意,[Serializable]对于,这不是必需的XmlSerializer

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

映射和序列化双向关联

来自分类Dev

序列化添加关联

来自分类Dev

序列化添加关联

来自分类Dev

序列化更新嵌套关联

来自分类Dev

序列化关联hasOne,belongsTo

来自分类Dev

用关联序列化创建对象

来自分类Dev

序列化1:n关联

来自分类Dev

序列化更新嵌套关联

来自分类Dev

C#类序列化映射

来自分类Dev

序列化结构的STL映射

来自分类Dev

序列化lambda函数的映射

来自分类Dev

Golang序列化和反序列化

来自分类Dev

序列化和反序列化HttpRequestMessage对象

来自分类Dev

json objcts的序列化和反序列化

来自分类Dev

序列化和反序列化对象集合

来自分类Dev

序列化和反序列化嵌套类

来自分类Dev

Symfony中的序列化和反序列化

来自分类Dev

儿童的序列化和反序列化

来自分类Dev

序列化和反序列化字符

来自分类Dev

序列化和反序列化javascript obj

来自分类Dev

如何序列化和反序列化 Hashtable?

来自分类Dev

mongodb c#驱动程序-继承,映射和序列化问题

来自分类Dev

使用“键”和“值”属性反序列化JSON映射不适用于Jackson

来自分类Dev

如何使用已加载的关联序列化/反序列化Ecto模型?

来自分类Dev

如何从序列化关联模型中获得价值?

来自分类Dev

Node.js序列化关联包括

来自分类Dev

序列化:尝试嵌套关联时出错

来自分类Dev

序列化:关联表查询上的“包含意外”

来自分类Dev

序列化自我关联会创建额外的列