我在遗留数据库中有两个表,我需要使用NHibernate进行映射。不幸的是,其中一个表正在使用复合键,我遇到了一个我在下面描述的问题。
首先,这是两个表的模式:
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
属性。它一直作为空列表返回,但我希望它在列表中有成员,因为数据库中有匹配的行。
有什么建议吗?我能做错什么?
答案 0 :(得分:0)
事实证明问题在于我将Percentages
集合声明为IList
而不是ICollection
。将声明更改为ICollection<BenchmarkFxRuleRatioHistory>
可以解决问题。