0

有人可以向我解释为什么会发生这种情况 - 我在客户和项目之间有一个一对多的映射。

以下是各自映射文件中的两种关系:

客户:

<!-- 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" />

以下是返回特定客户端的 Web 方法。

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: failed to lazily initialize a collection, no session or session was closed, here - //this is in the Client class

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

我经历了有关此异常的各种问题,但无法使其发挥作用。

4

2 回答 2

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>
于 2012-08-24T12:54:39.907 回答
1

您得到的异常是由于您尝试在ISession.
这可能会发生,因为在序列化时,序列化程序会读取该属性,并且它发生在您的using范围之外。
最好的办法是使用 dto 而不是序列化你的 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)方法将更合适且不易出错。

于 2012-08-24T19:54:43.940 回答