2012-08-24 51 views
0

有人可以向我解释为什么发生这种情况 - 我有一个一对多的客户端和项目之间的映射。NHibernate LazyInitializationException当返回一个对象

以下是在相应的映射文件中的两个关系:

客户:

<!-- Relationship with project --> 
<bag name="projects" cascade ="all-delete-orphan" lazy="false"> 
    <key column="client_id" /> 
    <one-to-many class="Project" ></one-to-many> 
</bag> 

项目:

<many-to-one name="client" 
     class="Client" 
     column="client_id" 
     cascade="all-delete-orphan" 
     fetch="join" 
     not-null="false" 
     lazy="false" /> 

以下是一个网络的方法,该方法返回一个特定的客户端。

public Client RetrieveEqualsClient(string propertyName, object propertyValue) 
{ 
    Client c = new Client(); 
    ConfigureNHibernate(); 
    using (ISession session = m_SessionFactory.OpenSession()) 
    { 
     ICriteria criteria = session.CreateCriteria(typeof(Client)); 
     criteria.Add(Expression.Eq(propertyName, propertyValue)); 
     c = criteria.List<Client>()[0]; 

     return c; 
    } 
} 

我把从我的aspx页面的方法如下:

$.ajax 
(
    { 
     type: "post", 
     url: "NHibernateWebService.asmx/RetrieveEqualsClient", 
     data: "{id: " + id + "}", 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     error: function (result) { alert("Failure: " + result.statusText); }, 
     success: function (result) { alert(result); }  
    } 
) 

这给了我一个例外:NHibernate的LazyInitializationException中:失败,没有会话或会话被关闭,懒洋洋地初始化集合在这里 - //这是在客户端类

public virtual IList<Project> projects 
{ 
    get { return c_projects ?? (c_projects = new List<Project>()); }//Exception Occurs Here! 
    set { c_projects = value; } 
} 

我大约有此异常的各种问题去了,但不能使它工作。

回答

1

尝试设置fetch="join"的项目:

<bag name="projects" cascade ="all-delete-orphan" fetch="join"> 
    <key column="client_id" /> 
    <one-to-many class="Project" ></one-to-many> 
</bag> 
1

你会得到异常的事实,你要加载的项目集合OUTSIDE的ISession的范围时造成的。
这可能是因为在序列化时,序列化程序读取了属性,并且发生在您的范围之外。
最好的办法是use a dto instead of serializing your POCO

所以,你的代码看起来是这样的:

using (ISession session = m_SessionFactory.OpenSession()) 
    { 
     ICriteria criteria = session.CreateCriteria(typeof(Client)); 
     criteria.Add(Expression.Eq(propertyName, propertyValue)); 
     var list = criteria.List<Client>(); 
     if (!list.Any()) 
      return null; 
     return new ClientDTO(list[0]); 
    } 

而且我不知道有关动态查询你从客户端获取属性的名称做。
您正在创建UI代码和数据库之间的强大耦合(如果Id属性发生更改,这意味着您必须更改jQuery代码...)

如果确实您的客户端始终要求一个使用Id的客户端,那么Get<Client>(id)方法会更合适,而且更不容易出错。

+0

我是设计网站和网络服务的新手,这是我第一次使用NHibernate。我不知道DTO是什么或如何使用它。我用解决方法解决了这个问题 - 我调用另一个名为EditClient()的函数,该函数又调用上面提到的'RetrieveEqualsClient()'。然后,我从检索到的客户端对象中创建了一个Json字符串。 我理解你的解释。但为什么只有在项目收集的get方法中才会发生这种情况。为什么不用简单的属性,如id,名称和电子邮件? – mridula

相关问题