使用Nhibernate懒惰代理与Web服务

时间:2011-07-30 11:34:16

标签: nhibernate soap xml-serialization lazy-evaluation proxy-classes

最近我在一段时间前写过的SOAP Web服务中遇到了一些性能问题。我注意到我有很多查询,我的hbm.xml映射充满了lazy = false语句。我升级到NHibernate 3.0并删除了lazy = false的东西,一切都很快......但现在我收到以下错误:

  

System.InvalidOperationException:生成XML文档时出错。 ---> System.InvalidOperationException:不期望UserProxy类型。使用XmlInclude或SoapInclude属性指定静态未知的类型。

User是一个类,我从类标记中删除了lazy = false属性,如下所示:

<class name="User" table="Users" >
  <id name="DatabaseID" unsaved-value="0" column="ID" type="integer" >
    <generator class="native"/>
   </id>
   <property name="IsExpert"/>
    .....more stuff here....
</class>

我的webservice有一个像这样的方法(简化了一点......在现实生活中,我在服务和nhibernate之间使用类似于存储库的模式):

    [WebMethod]
    public User GetUser(int userid)
    {
        session = GetCurrentSession();
        return session.Load<User>(userid);                         
    }

Web服务期望序列化用户,NHibernate给我一个UserProxy(完全不是用户)。我该怎样克服这个?

2 个答案:

答案 0 :(得分:2)

不要从Web方法返回实体。使用DTO。

答案 1 :(得分:0)

Webservices无法序列化代理 - session.Load(userId)将返回代理。您应该使用session.Get(userId)。

我认为说你应该使用DTO的答案没有帮助,DTO有时间和地点,有时你可能只想返回实体。

如果用户有子代理属性,我有一个类来处理这种情况。基本上它遍历所有属性(使用反射,并递归地遍历子对象和集合)并使用NHibernate.IsInitialized来检查属性是代理还是真正的文章。如果它是一个代理,那么它将它设置为null,从而使WCF可以将其序列化。