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

在NHibernate中将实体ID CSV列作为水合实体加载,nhibernate,Nhibernate,我有许多数据库表,如下所示: EntityId int : 1 Countries1: "1,2,3,4,5" Countries2: "7,9,10,22" 我希望NHibernate在加载我的EntityId时加载标识为1、2、3、4、5、7、9等的国家实体 这样做的原因是,我们希望避免联接的扩散,因为这些集合有几十个。在加载实体时是否必须获取国家/地区-可以接受运行查询来获取这些国家/地区?(您可以修改DAO以在获取实体后运行查询。)我询问的原因是,与加载实体时调用自定义代码相比,简单地

我有许多数据库表,如下所示:

EntityId int : 1
Countries1: "1,2,3,4,5"
Countries2: "7,9,10,22"
我希望NHibernate在加载我的EntityId时加载标识为1、2、3、4、5、7、9等的国家实体


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

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

创建实体后,您拥有Country1、Country2列表,您可以运行如下查询:

select c from Country c where c.id in (:Country1)
将:Country1作为命名参数传递。您还可以检索两组国家/地区的所有行

select Entity e where e.id in (:Country1, :Country2)
我希望country1和country2字符串可以按原样使用,但我感觉这行不通。如果是这样,则应将字符串转换为整数集合,并将该集合作为查询参数传递

编辑:使其更透明的“管道”以IInterceptor接口的形式出现。这允许您插入实体的加载、保存、更新、刷新等方式。您的实体将如下所示

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

       String Country1IDs;
       String Country2IDs;
       // protected getter and setter for NHibernate
   }
类MyEntity
{ 
IList Country1;
IList Country2;
//与公众接受者/接受者
字符串country1id;
字符串country2id;
//NHibernate的受保护吸气剂和设置器
}
尽管域对象具有列表的两种表示形式—实际实体和ID列表,但这与在实体中声明常规ID字段时发生的入侵相同。集合(country1和Country2)不会保留在映射文件中

有了它,您就可以提供一个IInterceptor实现来钩住加载和保存。加载时,获取countryXID属性的值,用于加载国家列表(如上所述)。保存时,将国家列表转换为ID列表,并保存该值


我找不到IInterceptor的文档,但是网上有很多项目在使用它。该接口如中所述。

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

创建实体后,您拥有Country1、Country2列表,您可以运行如下查询:

select c from Country c where c.id in (:Country1)
将:Country1作为命名参数传递。您还可以检索两组国家/地区的所有行

select Entity e where e.id in (:Country1, :Country2)
我希望country1和country2字符串可以按原样使用,但我感觉这行不通。如果是这样,则应将字符串转换为整数集合,并将该集合作为查询参数传递

编辑:使其更透明的“管道”以IInterceptor接口的形式出现。这允许您插入实体的加载、保存、更新、刷新等方式。您的实体将如下所示

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

       String Country1IDs;
       String Country2IDs;
       // protected getter and setter for NHibernate
   }
类MyEntity
{ 
IList Country1;
IList Country2;
//与公众接受者/接受者
字符串country1id;
字符串country2id;
//NHibernate的受保护吸气剂和设置器
}
尽管域对象具有列表的两种表示形式—实际实体和ID列表,但这与在实体中声明常规ID字段时发生的入侵相同。集合(country1和Country2)不会保留在映射文件中

有了它,您就可以提供一个IInterceptor实现来钩住加载和保存。加载时,获取countryXID属性的值,用于加载国家列表(如上所述)。保存时,将国家列表转换为ID列表,并保存该值


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

否您不能,至少不能使用默认功能

考虑到SQL中没有拆分字符串函数,任何ORM都很难在varchar列中检测到由逗号分隔的离散整数值。如果您(custom sql func)以某种方式克服了这个障碍,那么最好的办法就是使用某种组件/自定义用户类型,这种类型仍然会在“Country”表上创建大量连接,最终获取一组Country实体

…但我不确定这是否可以做到,这也意味着要从头开始编写持久性机制

作为旁注,我必须说我不理解设计决策;你对db进行了非规范化,那么,什么时候连接不好

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

更新: 再想一想,你可以作弊,至少对于选择的部分。 您可以创建一个视图,该视图将拆分这些值并将它们显示为单独的行:

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


然后您可以映射视图

不,您不能,至少不能使用默认功能

考虑到SQL中没有拆分字符串函数,任何ORM都很难在varchar列中检测到由逗号分隔的离散整数值。如果您(custom sql func)以某种方式克服了这个障碍,那么最好的办法就是使用某种组件/自定义用户类型,这种类型仍然会在“Country”表上创建大量连接来获取,