我很难找到有关如何优雅地序列化ActiveRecord对象的信息。
我们希望使用XML作为格式,因为我们需要输出我们的对象,使另一个程序能够切实解析它们。
XML-Serialization通常非常简单易用,但是在尝试序列化从ActiveRecord数据库返回的对象时会出现问题。数据库返回对象的代理类,其类型无法通过[XmlInclude]
属性明确预期。
例如:
public class Foo : ActiveRecordLinqBase<Foo>
{
public virtual string Bar{get;set;}
public virtual int FooId{get;set;}
public Foo(string bar)
{
Bar = bar;
}
public static void FooSerializeExample()
{
Foo tehFoozor = new Foo("omgFoo!");
tehFoozor.SaveAndFlush();
int id = tehFoozor.FooId;
//...
//Assume new ActiveRecord session.
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
Foo tehFoozorToSerialize = Foo.Find(id);
using(Stream stream = File.OpenWrite("tehFoozor.xml"))
{
serializer.Serialize(stream, tehFoozorToSerialize); //Will fail
}
}
}
在这里序列化时,我们会收到一条消息:
“不期望使用类型FooProxy2e2de24df9be42909d13a67fdb00b981。使用XmlInclude或SoapInclude属性指定静态未知的类型。”
其中代理类型将完全不可预测(至少据我所知)。
作为临时解决方案,我的团队已将每个AR对象的属性存根到接口中。然后,我们为每个实现了“Container”对象,这些对象基本上是对象的Xml-Serializable非AR版本。考虑到我们目前有18个不同的AR对象被序列化,我们的解决方案中有36个额外的文件!某事(一切)告诉我这是一个糟糕的解决方案,但我找不到更好的方法。
我们也尝试使用Soap Formatter,但是因为ActiveRecrodLinqBase&lt;&gt;不是“标记为可序列化”,这也是一个死胡同。
答案 0 :(得分:3)
急切地获取您需要的所有内容,然后使用AutoMapper将其映射到DTO并序列化这些DTO。
您获得的代理错误表明您的DTO实际上正在使用NHibernate的代理集合,而它们应该使用普通的List<T>
或数组。请务必使用ToList()
或类似内容。
此外,您不需要使用接口来映射DTO。
答案 1 :(得分:0)
尝试使用DataContractSerializer。
它的等效于[XmlInclude]是[KnownType],其中包含一个可以动态提供类型的版本,以便在第一次反映类型时包含该类型。见http://msdn.microsoft.com/en-us/library/ms730167.aspx
另外,我认为(虽然不是100%肯定).NET4.0将在DataContractSerializer中包含一个“Type Mapper”功能,这使得这样的场景更容易。
如果您最终尝试使用DCS并且会遇到问题,请将此评论作为评论发布,我会尝试回答这些问题。