如何在Hibernate中映射由查询支持的只读属性

时间:2010-08-25 09:41:21

标签: nhibernate nhibernate-mapping

我想知道如何最好地实现一个属性(此处为LatestRequest),该属性是只读的,由查询支持。

在这里,我有一个导出,可以请求多次发生。我想在Export上有一个属性来获取最新的ExportRequest。目前,我已经使用公式进行多对一映射,如下所示:

 <class name="Export" table="Exports">
   <id name="Id">
     <generator class="guid" />
   </id>
   <property name="Name" />
   <bag name="Requests" cascade="all,delete-orphan" inverse="true" access="field.camelcase" order-by="CreationDate desc">
     <key column="ExportId"/>
     <one-to-many class="ExportRequest"/>
   </bag>
   <many-to-one name="LatestRequest"
                class="ExportRequest"
                formula="(select top 1 ExportRequests.Id from ExportRequests order by ExportRequests.CreationDate desc)"/>
 </class>

 <class name="ExportRequest" table="ExportRequests">
   <id name="Id">
     <generator class="native" />
   </id>
   <many-to-one name="Export"
       class="Export"
       column="ExportId"
       not-null="true" />
   <property name="CreationDate" />
   <property name="Tag" />
 </class>

但是,由于在获取导出时会获取ExportRequests.Id LatestRequest,因此此访问模式会返回过时数据:

var export = session.Get<Export>(exportId);

export.AddRequest(new ExportRequest(DateTime.Now, "Foo"));

Assert.AreEqual("Foo", export.LatestRequest.Tag); // fails due to stale data

session.Update(export);

那么,实现LatestRequest属性的最佳方法是什么?

我可以更改LatestRequest的getter,以便它执行Find查询,该查询应该是最新的,但我不确定如何使导出知道会话。< / p>

1 个答案:

答案 0 :(得分:1)

有几种方法可以解决这个问题。我可能不会尝试以这种方式“自动”。为了提高性能和简单性,我只是将它作为常规引用并在业务逻辑或实体中进行管理,如下所示:

class Export
{
  private IList<ExportRequest> requests;

  ExportRequest LatestRequest { get; private set; }

  public void AddRequest (ExportRequest request)
  { 
    requests.Add(request);
    LatestRequest  = request;
  }
}

因此,您不需要任何特殊映射或任何其他查询来获取最新请求。而且,最重要的是,实体在内存中是一致的,并且不依赖于持久性。

无论如何解决它,实体和业务逻辑管理数据(在内存中)非常重要。应该是“坚持无知”。数据库和数据访问层不负责管理实体的关系和逻辑。