2011-07-07 13 views
0

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空のリストとして戻ってきますが、データベースに一致する行があるのでリストにメンバーがあると思います。

アドバイスはありますか?私は何が間違っていますか?

+0

問題はPercentagesプロパティマッピングであると思われますが、この問題は質問に表示されているHBMを持たないBenchmarkFxHedgeRuleマッピングにある可能性があります。すべての診断とSQLマッピングをキャプチャして、クエリが正しく構築されていることを確認するには、[configure log4net](http://nhforge.org/wikis/howtonh/configure-log4net-for-with-nhibernate.aspx) 。 –

答えて

0

それは、問題は、私はIListの代わりICollectionとしてPercentagesコレクションを宣言したということであったことが判明。宣言をICollection<BenchmarkFxRuleRatioHistory>に変更することで問題は解決します。

関連する問題