NHibernateを使用してマップする必要があるレガシーデータベースに2つのテーブルがあります。残念なことに、これらのテーブルの1つがコンポジットキーを使用しているので、私が以下で説明する問題にぶつかっています。コンポジットキーを使用した1対多のマッピングの問題
まず、ここでは2つのテーブルのスキーマは次のとおりです。
CREATE TABLE [dbo].[tBenchmarkFxHedgeHistory](
[BenchmarkFxHedgeHistoryId] [int] IDENTITY(1,1) NOT NULL,
[BenchmarkFxHedgeId] [int] NOT NULL,
[ModelId] [int] NOT NULL,
[BaseCurrencyCode] [nvarchar](5) NOT NULL,
[BenchmarkFxHedgeTypeId] [int] NOT NULL,
[DateFrom] [smalldatetime] NOT NULL,
[DateTo] [smalldatetime] NULL,
[PctHedgeBackToBase] [decimal](13, 10) NULL,
[Enabled] [bit] NOT NULL,
[BenchmarkHedgeStatusId] [int] NOT NULL,
[AuditActionId] [int] NOT NULL,
[Timestamp] [timestamp] NOT NULL,
[HistoryUser] [nvarchar](50) NOT NULL CONSTRAINT [DF_tBenchmarkFxHedgeHistory_HistoryUser] DEFAULT (suser_sname()),
[HistoryDate] [datetime] NOT NULL CONSTRAINT [DF_tBenchmarkFxHedgeHistory_HistoryDate] DEFAULT (getdate()),
CONSTRAINT [PK_tBenchmarkFxHedgeHistory] PRIMARY KEY CLUSTERED
(
[BenchmarkFxHedgeHistoryId] ASC
)
CREATE TABLE [dbo].[tBenchmarkFxHedgeRatio](
[BenchMarkFxHedgeId] [int] NOT NULL,
[NonBaseCurrencyCode] [nvarchar](5) NOT NULL,
[PctHedgeBackToBase] [decimal](13, 10) NOT NULL,
CONSTRAINT [PK_tBenchmarkFxHedgeRatio] PRIMARY KEY CLUSTERED
(
[BenchMarkFxHedgeId] ASC,
[NonBaseCurrencyCode] ASC
)
そしてここでは、ドメインクラスです:
public class BenchmarkFxHedgeRuleHistory
{
private IList<BenchmarkFxRuleRatioHistory> _percentages = new List<BenchmarkFxRuleRatioHistory>();
public virtual int Id { get; set; }
public virtual string BaseCurrencyCode { get; set; }
public virtual DateTime DateFrom { get; set; }
public virtual DateTime? DateTo { get; set; }
public virtual decimal? Percentage { get; set; }
public virtual bool Enabled { get; set; }
public virtual byte[] Timestamp { get; set; }
public virtual BenchmarkFxHedgeStatus Status { get; set; }
public virtual BenchmarkFxHedgeType Strategy { get; set; }
public virtual Model Model { get; set; }
public virtual BenchmarkFxHedgeRule Rule { get; set; }
public virtual AuditAction AuditAction { get; set; }
public virtual IList<BenchmarkFxRuleRatioHistory> Percentages
{
get { return _percentages; }
}
}
[Serializable]
public class BenchmarkFxRuleRatioHistory
{
public virtual string NonBaseCurrencyCode { get; set; }
public virtual decimal Percentage { get; set; }
public virtual BenchmarkFxHedgeRuleHistory HistoryEntry { get; set; }
public override bool Equals(object obj)
{
var rule = obj as BenchmarkFxRuleRatioHistory;
if (rule == null) return false;
return rule.HistoryEntry.Id == HistoryEntry.Id && NonBaseCurrencyCode == rule.NonBaseCurrencyCode;
}
public override int GetHashCode()
{
return NonBaseCurrencyCode.GetHashCode()^HistoryEntry.GetHashCode();
}
}
そして最後に、ここでは、NHibernateのマッピングファイルは、次のとおりです。
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping namespace="Tests.DomainModel" assembly="Tests.DomainModel" xmlns="urn:nhibernate-mapping-2.2">
<class name="BenchmarkFxHedgeRuleHistory" table="`tBenchmarkFxHedgeHistory`" schema="`dbo`">
<id name="Id" access="property" column="`BenchmarkFxHedgeHistoryId`">
<generator class="native" />
</id>
<many-to-one name="Rule" class="BenchmarkFxHedgeRule" column="`BenchmarkFxHedgeId`" not-null="true" fetch="select" />
<property name="BaseCurrencyCode" type="String" column="`BaseCurrencyCode`" length="5" />
<property name="DateFrom" type="DateTime" column="`DateFrom`" />
<property name="DateTo" type="DateTime" column="`DateTo`" />
<property name="Enabled" type="Boolean" column="`Enabled`" />
<property name="Percentage" type="Decimal" column="`PctHedgeBackToBase`" />
<property name="Timestamp" type="BinaryBlob" column="`Timestamp`" />
<many-to-one name="Status" class="BenchmarkFxHedgeStatus" column="`BenchmarkHedgeStatusId`" not-null="true" fetch="join" />
<many-to-one name="Strategy" class="BenchmarkFxHedgeType" column="`BenchmarkFxHedgeTypeId`" not-null="true" fetch="join" />
<many-to-one name="Model" class="Model" column="`ModelId`" not-null="true" fetch="select" />
<many-to-one name="AuditAction" class="AuditAction" column="`AuditActionId`" not-null="true" fetch="join" />
<bag name="Percentages" fetch="join" access="readonly" inverse="true" lazy="false" table="tBenchmarkFxHedgeRatioHistory" cascade="all-delete-orphan" subselect="">
<key column="`BenchmarkFxHedgeHistoryId`" />
<one-to-many class="BenchmarkFxRuleRatioHistory" />
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping namespace="Tests.DomainModel" assembly="Tests.DomainModel" xmlns="urn:nhibernate-mapping-2.2">
<class name="BenchmarkFxRuleRatioHistory" table="`tBenchmarkFxHedgeRatioHistory`" schema="`dbo`">
<composite-id>
<key-property name="NonBaseCurrencyCode" type="String" column="`NonBaseCurrencyCode`" />
<key-many-to-one name="HistoryEntry" class="BenchmarkFxHedgeRuleHistory" column="`BenchmarkFxHedgeHistoryId`" />
</composite-id>
<property name="Percentage" type="decimal" column="`PctHedgeBackToBase`" />
</class>
</hibernate-mapping>
これを次のコードで使用します:
using(var session = DataMapperConfiguration.SessionFactory.OpenSession())
{
var sessionRule = session.Get<BenchmarkFxHedgeRule>(id);
var historyList = session.Query<BenchmarkFxHedgeRuleHistory>()
.Where(x => x.Rule == sessionRule).ToList();
Assert.AreEqual(2, historyList[0].Percentages.Count);
}
sessionRule
は正しく水和されますが、historyList
の水分は正しく水和されていません。Percentages
空のリストとして戻ってきますが、データベースに一致する行があるのでリストにメンバーがあると思います。
アドバイスはありますか?私は何が間違っていますか?
問題はPercentagesプロパティマッピングであると思われますが、この問題は質問に表示されているHBMを持たないBenchmarkFxHedgeRuleマッピングにある可能性があります。すべての診断とSQLマッピングをキャプチャして、クエリが正しく構築されていることを確認するには、[configure log4net](http://nhforge.org/wikis/howtonh/configure-log4net-for-with-nhibernate.aspx) 。 –