【发布时间】:2011-02-25 21:50:36
【问题描述】:
这是一个关于当必须通过 http 和 tcp 传输在应用程序之间传递 ORM 模型时如何处理它们的一般性问题,但特别是我通过 Castle Active Record 使用 NHibernate,如果它有任何区别的话。传输中的数据格式可以是 JSON,也可以是 XML。
在通过传输传递 ORM 模型时遇到了三个问题:
XML/JSON 序列化时出现循环引用错误。这些错误可以通过在关系属性上使用 ScriptIgnore 和 XmlIgnore 属性来解决,但这不是一个很好的解决方案,因为有时您希望包含被忽略的相关对象,如果您删除忽略属性,您可能会在其他地方导致循环引用错误。
序列化时延迟加载。假设你有一个类 A,它与类 B 有 1:1 的关系。你序列化类 A,它会尝试调用数据库来获取和序列化类 B。有时你不再处于允许延迟加载的正确会话中在序列化时会引发错误。这也可以通过忽略属性来解决,但出于同样的原因,这不是一个好的解决方案。
ORM 模型的基类不能序列化为 XML,而是密封的。我不知道有什么解决方案,但我遇到过很多次。
上述问题的一个解决方案是根本不跨传输来回传递 ORM 模型,我听到很多人说这是推荐的解决方案。但是,您如何以干净的方式执行此操作?假设您有 ModelA,您想使用某种传输方式将其从一个应用程序传递到另一个应用程序。
您创建了一个 ModelAView 类,它具有 ModelA 的所有属性,但没有所有 ORM 属性、基类和延迟加载功能。解决方案已经不干净了,因为您现在有 2 个具有相同重复属性的类。当您想对模型进行更改时,您必须在两个类中进行更改。
您从数据库中获取 ModelA 实例,并且必须逐字段填充 ModelAView 的属性。也许你有一个 ModelAView 的构造函数,它传入一个 ModelA 实例,并在那里设置属性,这样它就更干净了。但是,您仍然必须按属性设置 values 属性,这可能很麻烦。您可以尝试执行某种克隆功能,但是如果它有子对象,那么您需要深度克隆,而且似乎没有一个好的方法可以做到这一点,特别是因为 View 类不一定有所有具有与 ModelA 类相同的属性。
您将 ModelAView 通过传输传递给其他应用程序。
希望其他应用程序可以使用 ModelAView 来完成它需要做的任何事情。但是,如果它需要更新 ModelA 的属性并将它们保存到数据库中,则需要执行相反的操作,将 ModelAView 中的所有属性复制到 ModelA 中,然后保存到数据库中。
所以我在这里写了很多,但我希望我已经阐明了在这些情况下处理 ORM 模型时遇到的挑战。有没有人有任何经验可以分享他们尝试过的真实方法来处理这些不需要重复代码和/或将值从一个对象复制到另一个对象的属性的问题?
【问题讨论】:
标签: nhibernate orm castle-activerecord