我是一名正在尝试使用Nhibernate + WCF + WPF的.Net n层应用程序的学生。
其中一件非常糟糕的事情就是对象图序列化,事实上它根本没有完成,目前关联被忽略了,我们在任何地方都在使用DTO。
据我所知,一个方法可以预先定义哪些对象和集合应该被加载和序列化以通过网络,从而能够向客户端呈现一些关联,但是这看起来有限,不灵活且不一致(你能否说我不喜欢这个想法)。
我遇到的一个选择是简单地用客户端层上的延迟加载集合替换NHProxies,其中“disconnectedProxy”将通过线路检索相关的东西。这意味着我们必须稍微扩展我们的Web服务签名并对我们生成的代理做一些hackery,但这似乎是一个很好的T4 /其他代码生成实验。
据我所知,这似乎是一个常见的绊脚石,但经过大量阅读后,我无法找出任何好的/普遍接受的解决方案。我正在寻找与任何特定解决方案一样的方向,但如果有一种简单的方法让客户“感觉”连接,请告诉我。
答案 0 :(得分:6)
你问一个非常好的问题,遗憾的是没有一个非常干净的答案。即使您能够通过WCF进行延迟加载(我们能够做到),您仍然会遇到使用代理拦截器的问题。相信我,你想要客户层上的POCO对象!
你真正需要考虑的是......从我所见过的研究中被认为是解决这个问题的行业标准方法,被称为持久性与使用或持久性无知。换句话说,您的对象模型和映射表示您的持久性域,但它与您的理想使用方案不匹配。您不想将整个数据库放到客户端只是为了显示几个属性吗?
这似乎是一个简单的问题,但解决方案要么非常简单,要么非常复杂。一方面,您可以围绕使用场景设计实体,但最终会导致对象域的扩散,从而难以维护。另一方面,您仍然需要富对象模型关系才能编写精细的业务逻辑。
为了简化这个问题,我们来看看我们需要填补数据库和数据库/服务层之间以及服务到客户端差距的两个主要差距。 NHibernate通过提供ORM将数据加载到对象中来填充第一个。它做得不错,但为了获得出色的性能,需要使用自定义加载策略进行调整。我离题了......
服务器和客户端之间的第二个差距是事情变得冒险。为了简化,假设您没有通过网络将任何映射实体发送到客户端?尝试创建一种机制,将业务实体交换为DTO对象,同样将DTO对象交换为业务实体。这样,您的客户只处理DTO(当然是POCO),您的业务逻辑可以保持其丰富的结构。这使您不仅可以利用NHibernate的延迟加载机制,还可以利用会话的其他好处,例如L1缓存。
出于简洁和知识产权的原因,我不会进入上述机制的设计,但希望这足以指出您正确的方向。如果您根本不关心性能或延迟......只需将延迟加载一起关闭并完成序列化问题。
答案 1 :(得分:1)
对我来说已经有一段时间了,但是注入/断开连接的代理可能没有听起来那么糟糕。因为你是一名学生,我会假设你有一些时间,并想稍微捣乱。
如果要注入自己的自定义序列化/反序列化逻辑,可以使用可以使用IDataContractSurrogate应用的DataContractSerializerOperationBehavior。我只做了一些基本的事情,但可能值得研究。通过在此层添加一些有趣的逻辑(读取:可能是hackish),您可以使其更加连接。
Here是关于某人实现相同实现的MSDN帖子,NHibernate使用的DynamicProxy使得无法直接序列化延迟加载的NHibernate对象。
答案 2 :(得分:0)
如果您确实想要通过网络传输对象图并保留延迟加载功能。看看我在这里制作的一些代码http://slagd.com/?page_id=6。基本上它会在线路的另一端创建一个假会话,并允许nhibernate代理保留其功能。不是说这是正确的做事方式,但它可能会给你一些想法。