NHibernate:在映射中指定的复合键以外的其他键上加入集合

NHibernate:在映射中指定的复合键以外的其他键上加入集合,nhibernate,join,hql,composite-key,Nhibernate,Join,Hql,Composite Key,在遗留数据库中,我必须使用通过组合键关联的嵌套表。翻译成NHibernate,例如,我有一个FcoTransportation类,它有一个FcoConsignment类的子类集合。但是,在一种情况下,我希望仅基于复合键的一个组件加载集合,而忽略另一个组件 映射如下所示: <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-laz

在遗留数据库中,我必须使用通过组合键关联的嵌套表。翻译成NHibernate,例如,我有一个FcoTransportation类,它有一个FcoConsignment类的子类集合。但是,在一种情况下,我希望仅基于复合键的一个组件加载集合,而忽略另一个组件

映射如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
  <class name="FcoLib.FcoTransportation, FcoLib" table="FCO_TRANSPORTATION">
    <composite-id>
    <key-property name="ID"/>
  <key-property name="FK_EventID"/>
</composite-id>
<!--...snip...-->
<bag name="Consignments" table="FCO_Consignment" lazy="false" cascade="save-update">
  <key>
    <column name="FK_TransportationID"/>
    <column name="FK_EventID"/>
  </key> 
  <one-to-many class="FcoLib.FcoConsignment, FcoLib"/>
</bag>
<!--...snip...-->

更新:有人建议使用连接提取,这看起来很有希望,但仍然没有提取子项:

 String queryString = "select ft from FcoTransportation as ft where ft.ID ='" + guid + "'";
 queryString += " join fetch ft.Consignments as fc on fc.FK_TransportationID = '" + guid + "'";

更新:还建议进行所谓的“theta样式”联接,如下所示,但在这里,未填充子集合:

String queryString  = "select ft from FcoTransportation as ft, FcoConsignment as fc"
                    + " where ft.ID = fc.FK_TransportationID"
                    + " and ft.ID = '" + guid + "'";


注意:我只需要取出数据,不需要再次保存。我已经有了一个查询来获取每一次运输的货物(最多是几十件,但通常是几件,在一些孤立的情况下是几百件)。我只想节约往返数据库的次数。这就是为什么我希望货物在运出的同时被提取

当前您只是加入而不是获取子项,因此请尝试使用“加入获取”而不是仅加入:

select ft from FcoTransportation as ft join fetch ft.Consignments as fc on fc.FK_TransportationID = :ID
那就可以了。

试试这个

select ft from FcoTransportation as ft, FcoConsignment as fc
where ft.Id = fc.Transportation.Id

我不知道从FCoConsign到FcoTransportation的导航属性的名称,所以我将其命名为Transportation

我认为你采取了错误的方法。一对多关系映射是关系数据库中外键关系的面向对象等价物。在这种情况下,筛选或获取子集合的不同视图的功能没有意义。假设您可以做到这一点,NHibernate如何将更改持久化到已筛选的子集合?如果NHibernate不能持久化它,那么它的建模就不正确。您还希望“通过在“ChangedDate”和“ChangedTime”两列中优先选择那些具有最高值的条目来删除任何重复的子项,这强化了这一结论

我只需要创建一个查询来返回您想要的货物。使用Future,您可以将其封装在一个方法中,该方法将在数据库的一次访问中返回FcoTransportation对象和查询结果


另一个选项是向FcoTransportation添加一个方法,用于过滤子集合。如果托运数量合理(这听起来很有希望,但我无法让它发挥作用。我已经更新了我的问题供您查看。不。我认为它应该真正涉及某种联接。我使用的联接类型称为“theta样式联接”。在发布我的答案之前,我会在测试域上检查它们。很有趣!这应该也会填充子集合?但它也不起作用,miracleforhire的其他建议也不起作用,所以可能还有其他问题。你能发布你试图获取的实际SQL吗?谢谢。如果我有什么做错了,那么我会在这种特殊情况下,我不需要使用NHibernate。我只需要从表中取出数据,而不需要再次保存它们,因此打乱父子关系对我来说并不是一个真正的问题。我只需要以最有效的方式将其取出并发送出去。我已经有了一个查询来获取每一次运输的货物(最多是几十个,但通常是几个,在某些个别情况下是几百个)。我只想节约数据库的往返次数。NHibernate适用于这种情况,您可以将数据库的往返次数减少到1,但可能不会减少查询的次数。我不认为您可以使用联接来实现这一点。如何将数据库的往返次数减少到1?我可能没有应用NHibernate最经济的用法会话和事务…Thnx。
select ft from FcoTransportation as ft join fetch ft.Consignments as fc on fc.FK_TransportationID = :ID
select ft from FcoTransportation as ft, FcoConsignment as fc
where ft.Id = fc.Transportation.Id