0

我有一个Model类,其中包含Messages 和Signals 的列表。

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

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

我的想法是将 a 存储List<uint> SignalIndicesMessage类中,其中包含信号的索引,因为它们在Model.Signals列表中。但是,假设 XmlSerializer 在序列化/反序列化时不会弄乱索引是否安全?此外,这种方法意味着Message.Signals获取[XmlIgnore]属性并依赖另一个使用SignalIndices列表的 Linq 来实现与Signal.Messages.

换句话说,是否有可能通过与 MessageCollection 和 SignalCollection 类一起使用的类似技术来始终确保数据一致性(也在反序列化过程中,其中对象构造的顺序未定义),同时还具有“真实"List<Signal>不使用 Linq 的 Message 类中的信号 ( ) 列表?

4

2 回答 2

1

如果在 signalcollection 中对模型的引用纯粹是为了设置模型属性,您可以在消息本身中使用 signalcollection 类

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

或者有一个从 List 派生的新信号类,它公开了一个模型属性。

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

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;
    }
}
于 2012-07-04T10:33:49.927 回答
1

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

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

这与大多数数据库中处理多对多关系的方式非常相似。

于 2012-07-04T10:34:22.630 回答