我有一个Model类,它包含Message和Signal的列表。
每个Message可以包含0、1或更多个信号。一个Signal可以同时包含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(); }
}
}我的想法是在Message类中存储一个List<uint> SignalIndices,它包含信号在Model.Signals列表中的索引。然而,假设XmlSerializer在序列化/反序列化时不会弄乱索引,这样做安全吗?此外,这种方法意味着Message.Signals将获得[XmlIgnore]属性,并依赖于使用SignalIndices列表的另一个Linq,以实现与Signal.Messages中类似的功能。
换句话说,有没有可能通过与MessageCollection和SignalCollection类使用的类似技术来确保数据的一致性(也可以在反序列化过程中,其中对象构造的顺序是未定义的),同时在不使用Linq的消息类中拥有一个“真正的”信号列表(List<Signal>)?
发布于 2012-07-04 18:34:23
如果将唯一的id添加到消息和信号中,那么可以添加一个新的MessageSignals单例类,该类将序列化为消息id和信号id的键值对。然后,您可以序列化和反序列化所有消息、所有信号和所有MessageSignal对。然后,您将使用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-04 18:33:50
如果信号集合中对model的引用纯粹是为了设置model属性,那么您可以在消息本身中使用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; }
}
}或者从公开模型属性的列表派生新的信号类。
如果上面不是一个选项,你可以在模型中添加一个在反序列化后触发的方法(通过使用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;
}
}https://stackoverflow.com/questions/11327103
复制相似问题