C#Castle ActiveRecord:如何优雅地(XML)序列化ActiveRecord对象?

时间:2009-10-08 16:54:10

标签: c# xml-serialization castle-activerecord

我很难找到有关如何优雅地序列化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;不是“标记为可序列化”,这也是一个死胡同。

2 个答案:

答案 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并且会遇到问题,请将此评论作为评论发布,我会尝试回答这些问题。

相关问题