首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Xml(反)序列化时维护多对多关系

在Xml(反)序列化时维护多对多关系
EN

Stack Overflow用户
提问于 2012-07-04 18:18:57
回答 2查看 521关注 0票数 0

我有一个Model类,它包含MessageSignal的列表。

每个Message可以包含0、1或更多个信号。一个Signal可以同时包含0条、1条或更多条消息。在使用XmlSerializer进行反序列化时,我在维护消息和信号之间的关系时遇到了麻烦,同时也避免了重复的对象(在我的应用程序中,除了XmlSerializer之外,不可能使用任何其他对象)。

代码语言:javascript
运行
复制
class Model
{
    private MessageCollection messages;
    public MessageCollection Messages { get { return messages; } }

    private SignalCollection signals;
    public SignalCollection Signals { get { return signals; } }

    public Model()
    {
        // the collection classes automatically set the Model property of any
        // Messages/Signals added to its appropriate owner (this)
        this.messages = new MessageCollection(this);
        this.signals = new SignalCollection(this);
    }
}

class Message
{
    [XmlIgnore] // set by MessageCollection
    public Model Model { get; set; }

    public List<Signal> Signals
    {
        get { ??? }
    }
}

class Signal
{
    [XmlIgnore] // set by SignalCollection
    public Model Model { get; set; }

    public List<Message> Messages
    {
        get { return this.Model.Messages.Where(x => x.Signals.Contains(this)).ToList(); }
    }
}

我的想法是在Message类中存储一个List<uint> SignalIndices,它包含信号在Model.Signals列表中的索引。然而,假设XmlSerializer在序列化/反序列化时不会弄乱索引,这样做安全吗?此外,这种方法意味着Message.Signals将获得[XmlIgnore]属性,并依赖于使用SignalIndices列表的另一个Linq,以实现与Signal.Messages中类似的功能。

换句话说,有没有可能通过与MessageCollection和SignalCollection类使用的类似技术来确保数据的一致性(也可以在反序列化过程中,其中对象构造的顺序是未定义的),同时在不使用Linq的消息类中拥有一个“真正的”信号列表(List<Signal>)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-04 18:34:23

如果将唯一的id添加到消息和信号中,那么可以添加一个新的MessageSignals单例类,该类将序列化为消息id和信号id的键值对。然后,您可以序列化和反序列化所有消息、所有信号和所有MessageSignal对。然后,您将使用MessageSignal类作为查找来获取消息的所有信号

代码语言:javascript
运行
复制
  public IEnumerable<Signal> Signals
  {
    get
    {
      return from signal in Signals
      from ms in MessageSignals
      where ms.MessageId == this.MessageId && ms.SignalId==signal.Id
      select signal;
    }
  }

它非常类似于在大多数数据库中处理的多对多关系。

票数 1
EN

Stack Overflow用户

发布于 2012-07-04 18:33:50

如果信号集合中对model的引用纯粹是为了设置model属性,那么您可以在消息本身中使用signalcollection类

代码语言:javascript
运行
复制
class Message
{
    [XmlIgnore] // set by MessageCollection
    public Model Model { get{return signals==null ? null : signals.Model;} set{signals=new SignalCollection(value);} }

    SignalCollection signals;
    public SignalCollection Signals
    {
        get { return signals; }
    }
}

或者从公开模型属性的列表派生新的信号类。

如果上面不是一个选项,你可以在模型中添加一个在反序列化后触发的方法(通过使用OnDeserializedAttribute )

代码语言:javascript
运行
复制
class Model
{
     [OnDeserialized]
     private void restoreModelSignals(StreamingContext context)
    {
        //bit of linq here though
        foreach(var s in messages.SelectMany(m=>m.Signals))
             s.Model=this;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11327103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档