You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NHibernate中映射计算得出的List类型属性?

问题描述

我的模型包含以下属性:

public virtual DateTime LastSessionDate { get; set; }
public virtual List<double> Values { get; set; }

其中LastSessionDate通过<property>的formula属性映射自定义SQL查询,运行正常:

<property name="LastSessionDate" formula="(select ...)" />

但Values属性需要从其他表通过自定义SQL查询获取,尝试多种<bag>和<subselect>组合均未成功。使用以下配置时抛出NHibernate.MappingException异常:persistent class not known: System.Collections.Generic.List1[[System.Double]]`

<many-to-one name="Values" access="readonly">
   <formula>(select ...)</formula>
</many-to-one>
解决思路

1. 纠正映射类型:用值类型集合映射而非many-to-one

many-to-one用于映射单个实体关联,而List<double>是值类型集合,需要用<bag>或<list>(对应.NET的ICollection<T>或IList<T>)来映射,搭配<element>指定值类型。

2. 使用subselect定义自定义查询

通过subselect属性直接指定获取集合数据的SQL查询,需确保查询返回两列:

  • 关联当前实体的外键列(需与当前实体主键匹配)
  • 存储double值的列

示例配置:

<!-- 假设当前实体主键为Id,查询返回entity_id(关联主键)和value(double值) -->
<bag name="Values" access="readonly" subselect="select entity_id, value from other_table where [你的过滤条件]" lazy="false">
  <key column="entity_id" /> <!-- 关联当前实体的主键 -->
  <element type="Double" column="value" /> <!-- 指定集合元素类型和对应列 -->
</bag>

3. 替代方案:使用内联表定义

如果需要更灵活的SQL,也可以直接在table属性中嵌套子查询:

<bag name="Values" access="readonly" table="(select entity_id, value from other_table where [你的过滤条件])" lazy="false">
  <key column="entity_id" />
  <element type="Double" column="value" />
</bag>

注意事项

  • 确保子查询返回的外键列(如entity_id)与当前实体的主键列完全匹配,NHibernate会自动将当前实体的主键值代入查询,过滤出对应的数据
  • 如果不需要懒加载,设置lazy="false"可确保集合在加载实体时一并获取
  • 若需保持List的顺序,可改用<list>并指定<index>列,但需确保子查询返回顺序相关的列(若自定义SQL有排序逻辑,<bag>也能保留结果顺序,但NHibernate不保证<bag>的顺序稳定性)

内容的提问来源于stack exchange,提问作者jgayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 12:22:51