背景:
我正在处理一个遗留的 DB2 数据库,所以我无法控制模式。我已经在这个网站上搜索了答案,但没有找到。我也搜索了谷歌并没有找到合适的答案。
这里描述的表都使用复合键。我有一个父表存储每个“案例”的资格信息。子表存储与案例相关的每个人的资格信息。子记录由 pin 号区分,以使它们仅在子表中唯一。
我正在使用 NHibernate v3.1 和 Fluent NHibernate v1.2,两者都是通过 NuGet 包获得的。使用 Fluent NHibernate 自动映射器功能映射实体。任何自定义映射都是在每个实体的映射覆盖方法中完成的。
要知道的另一件事是,这些表没有在 DB2 中定义的“主键”。它们只有“唯一键”,这是您在下面的复合键定义中看到的(参见代码)。
T0026_AG_ELIG 是父表的名称和对应的 POCO 类。
T0265_AG_IN_ELIG 是子表的名称和对应的 POCO 类。
问题:
问题是当我执行查询时,所有数据都被查询到,父记录成功映射到类,但是返回的子行没有映射到父类上的集合。NHibernate 确实为父数据和子数据生成查询。当我对数据库执行自己的查询时,条件的正确数据确实会返回。出于某种原因,子记录只是没有绑定到父 (T0026) 类的属性。
问题:
我需要做什么才能让从 T0265_AG_IN_ELIG 返回的多行映射到其相应的类并正确加载到父类 (T0026_AG_ELIG) 上的指定集合属性中?
父集合属性 (T0026_AG_ELIG):
Public Overridable Property IndividualEligibilityRecords As IList(Of T0265_AG_IN_ELIG)
父级映射覆盖 (T0026_AG_ELIG):
mapping.CompositeId() _
.KeyProperty(Function(x) x.CASE_NUM) _
.KeyProperty(Function(x) x.PROGRAM_CD) _
.KeyProperty(Function(x) x.SUBPROGRAM_CD) _
.KeyProperty(Function(x) x.AG_SEQ_NUM) _
.KeyProperty(Function(x) x.CAG_ELIG_SEQ_NUM)
mapping.HasMany(Of T0265_AG_IN_ELIG)(Function(x) x.IndividualEligibilityRecords) _
.Cascade.All() _
.Inverse() _
.Fetch.Join() _
.KeyColumns.Add("CASE_NUM") _
.KeyColumns.Add("PROGRAM_CD") _
.KeyColumns.Add("SUBPROGRAM_CD") _
.KeyColumns.Add("AG_SEQ_NUM") _
.KeyColumns.Add("CAG_ELIG_SEQ_NUM") _
.Not.LazyLoad() _
.AsList(Function(x) x.Column("PIN_NUM"))
mapping.IgnoreProperty(Function(x) x.IndividualEligibilityRecords)
子级映射覆盖 (T0265_AG_IN_ELIG):
mapping.CompositeId() _
.KeyProperty(Function(x) x.CASE_NUM) _
.KeyProperty(Function(x) x.PROGRAM_CD) _
.KeyProperty(Function(x) x.SUBPROGRAM_CD) _
.KeyProperty(Function(x) x.AG_SEQ_NUM) _
.KeyProperty(Function(x) x.CAG_ELIG_SEQ_NUM) _
.KeyProperty(Function(x) x.PIN_NUM)
执行以下代码以执行查询:
transaction = session.BeginTransaction()
query = session.CreateQuery("FROM T0026_AG_ELIG AS T0026 " _
& "WHERE T0026.CASE_NUM = :p0 AND T0026.PROGRAM_CD = :p1 AND " _
& "SUBPROGRAM_CD = :p2 AND AG_SEQ_NUM = :p3 AND CAG_ELIG_SEQ_NUM = :p4")
query.SetParameter("p0", caseNumber)
query.SetParameter("p1", programCode)
query.SetParameter("p2", subProgramCode)
query.SetParameter("p3", agSequenceNumber)
query.SetParameter("p4", cagEligSequenceNumber)
result = query.List()
transaction.Commit()
If result.Count = 1 Then
Return DirectCast(result.Item(0), T0026_AG_ELIG)
End If