1

我很难找到有关如何优雅地序列化 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 对象的属性存根到接口中。然后,我们为每个对象实现了“容器”对象,它们本质上是对象的 Xml-Serializable 非 AR 版本。考虑到我们目前有 18 个不同的 AR 对象被序列化,这是我们解决方案中的 36 个附加文件!有些东西(一切)告诉我这是一个糟糕的解决方案,但我一直无法找到更好的方法。

我们也尝试使用 Soap Formatter,但由于 ActiveRecrodLinqBase<> 没有“标记为可序列化”,这也是一个死胡同。

4

2 回答 2

3

急切地获取您需要的所有内容,然后使用AutoMapper将其映射到 DTO 并序列化这些 DTO。

您收到的代理错误表明您的 DTO 实际上正在使用 NHibernate 的代理集合,而它们应该使用普通List<T>或数组。确保您使用ToList()或类似的。

此外,您不需要使用接口来映射 DTO。

于 2009-10-08T21:18:12.857 回答
0

试试 DataContractSerializer。

[XmlInclude] 的等价物是 [KnownType],它包括一个可以动态提供类型以在第一次反映类型时包含的版本。请参阅http://msdn.microsoft.com/en-us/library/ms730167.aspx

此外,我认为(虽然不是 100% 肯定).NET4.0 将在 DataContractSerializer 中包含一个“类型映射器”功能,它专门使这样的场景更容易。

如果您最终尝试了 DCS 并且会遇到问题,请将此答案作为评论发布,我将尝试回答。

于 2009-10-09T08:52:02.297 回答