バックグラウンド:
私はレガシーDB2データベースで作業しているので、スキーマを制御できません。このサイトで回答を検索しましたが、見つかりませんでした。私もグーグルを検索しましたが、適切な答えが見つかりませんでした。
ここで説明する表は両方とも複合キーを利用しています。「ケース」ごとの適格性情報を格納する親テーブルがあります。子テーブルには、ケースに関連付けられている各個人に関する適格性情報が格納されます。子レコードはピン番号で区別され、子テーブルでのみ一意になります。
NHibernatev3.1とFluentNHibernatev1.2を使用していますが、どちらもNuGetパッケージを介して取得しています。エンティティは、FluentNHibernate自動マッパー機能を使用してマッピングされます。カスタムマッピングは、各エンティティのマッピングオーバーライドメソッドで実行されます。
もう1つ知っておくべきことは、これらのテーブルには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