2010-06-08 49 views
1

我有一些数据库表中,看起来像这样:加载实体ID CSV列水合实体NHibernate的

EntityId int : 1 
Countries1: "1,2,3,4,5" 
Countries2: "7,9,10,22" 

我想有NHibernate的加载identifed为1,2,3的国家实体,4,5,7,9等,只要我的EntityId加载。

之所以这样做,是因为我们希望避免连接的扩散,因为这些集合有几十个。

+0

你可以给一些数据库模式,类,映射? – Jaguar 2010-06-16 11:14:35

+0

+1正常情况下,我偏离了集合的字段,但我发现这可能很有用,并且hibernate中的实现看起来很简单。 – mdma 2010-06-16 23:39:24

回答

1

提取国家必须发生的实体加载 - 你可以接受运行查询来获取这些? (您可以修改您的DAO以在获取实体后运行查询)。我问的原因是,只需运行查询,而不是在加载实体时调用自定义代码,这需要较少的“管道”和框架内部。

fecthing你的实体后,你有国家1,COUNTRY2列表,您可以运行类似查询:

select c from Country c where c.id in (:Country1) 

传:国家1作为命名的参数。您也culd检索所有行这两组国家

select Entity e where e.id in (:Country1, :Country2) 

我希望,因为他们是国家1 & COUNTRY2字符串可以使用的,但我有一种感觉,这是行不通的。如果是这样,您应该将字符串转换为整数集合,并将该集合作为查询参数传递。

编辑:使“更透明”的“管道”以IInterceptor接口的形式出现。这可以让你插上实体如何加载,保存,更新,刷新等你的实体将这个样子

class MyEntity 
    { 
     IList<Country> Country1; 
     IList<Country> Country2; 
     // with public getter/setters 

     String Country1IDs; 
     String Country2IDs; 
     // protected getter and setter for NHibernate 
    } 

东西虽然域对象具有列表的两种表示 - 实际的实体,以及ID列表,这与在实体中声明常规ID字段时具有相同的入侵。集合(country1和Country2)不会保存在映射文件中。

有了这个,您可以提供一个IInterceptor实现,用于挂载加载和保存。在加载时,您可以获取countryXID属性的值,用于加载国家/地区列表(如上所述)。在保存时,您将各国的IList转换为ID列表并保存该值。

我找不到IInterceptor的文档,但网上有很多项目使用它。该界面在this article中描述。

+0

这需要较少的(不)管道,但在我看来,这是一种错误的方法,因为你失去了领域中的持续性无知。我试图找出什么是我需要放置的管道 – 2010-06-18 05:38:01

+0

我不确定你会得到你想要的,即非关系映射,但强制所有处理在持久层完成。另外请记住,hibernate可以将主实体和集合中的对象作为单个SQL语句(使用连接)来获取。如果避免了连接,那么您将至少需要2次查询。附加查询的延迟可能比连接花费更多。 – mdma 2010-06-18 10:52:11

+0

在我遇到的问题中,实际上有14个这样的组,而不是两个,就像这个例子。我开始认为这是不可能的。 – 2010-06-18 11:41:11

0

不,你不能,至少没有默认的功能。

考虑到SQL中没有SPLIT字符串函数,任何ORM都很难检测由varchar列中的逗号分隔的谨慎整数值。如果你以某种方式克服了这个障碍,那么你最好的办法就是使用某种组件/自定义用户类型,它仍然可以在'Country'表上进行连接的加密,最终获取一个集合的国家实体...

...但我不确定它可以完成,它也意味着从头开始写持久性机制。

作为一个便笺,我必须说我不明白设计决定;你反分贝数据库,以及,因为当联接是坏的?

此外,另一个给定的答案将解决您的问题,无需重新设计您的数据库,并且无需编写大量实验管道代码。但是,它不会回答你的问题,因为国家实体的水合作用

更新: 第二个想法,你可以作弊,至少对于选择部分。 你可以做一个视图将拆分值并显示它们作为单独的行:

Entity-Country1 View: 
EntityId Country 
1  1 
1  2 
1  3 

Entity-Country2 View: 
EntityId Country 
1  7 
1  9 
1  10 

然后,你可以映射视图