将实体ID CSV列加载为NHibernate中的水合实体

时间:2010-06-08 20:17:36

标签: nhibernate

我有一些数据库表,如下所示:

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

我希望每当我的EntityId加载时,NHibernate都会加载标识为1,2,3,4,5,7,9等的国家/地区实体。

这样做的原因是我们希望避免连接的增加,因为这些集合中有很多。

2 个答案:

答案 0 :(得分:1)

在加载实体时是否必须提取国家/地区 - 您可以运行查询来获取这些内容吗? (您可以修改DAO以在获取实体后运行查询。)我问的原因是,与在加载实体时调用自定义代码相比,简单地运行查询需要更少的“管道”和框架内部。

在对您的实体进行处理后,如果您拥有Country1,Country2列表,则可以运行如下查询:

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

传递:Country1作为命名参数。您还会检索两组国家/地区的所有行

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中描述。

答案 1 :(得分:0)

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

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

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

作为旁注,我必须说我不理解设计决定;你对db进行了非规范化,好吧,因为当连接不好时?

此外,另一个给出的答案将解决您的问题,而无需重新设计您的数据库,并且无需编写大量实验性管道代码。但是,它不会回答您关于国家实体水化的问题

更新: 在第二个想法,你可以作弊,至少对于选择部分。 您可以创建一个VIEW,它将分割值并将它们显示为单独的行:

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

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

然后你可以映射视图