2010-03-17 123 views
1

比方說,你有如下表結構:需要與NHibernate /功能NHibernate映射幫助

    ============================== 
        | Case      | 
        ============================== 
        | Id   | int   | 
        | ReferralType | varchar(10) | 
     +---------| ReferralId | int   |---------+ 
     |   ==============================   | 
     |      |       | 
     |      |       | 
====================== ====================== ======================   
| SourceA   | | SourceB   | | SourceC   | 
====================== ====================== ====================== 
| Id | int   | | Id | int   | | Id | int   | 
| Name | varchar(50) | | Name | varchar(50) | | Name | varchar(50) | 
====================== ====================== ====================== 

基礎上ReferralType的ReferralId包含ID爲SourceA,SourceB,或SourceC

我試圖弄清楚如何使用Fluent NHibernate或簡單的NHibernate將其映射到對象模型中。我嘗試了一堆不同的東西,但我沒有成功。有任何想法嗎?

對象模型可能是這樣的:

public class Case 
{ 
    public int Id { get; set; } 
    public Referral { get; set; } 
} 

public class Referral 
{ 
    public string Type { get; set; } 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 
+0

你是如何得出這樣的圖表?用手? – Dann 2010-03-24 19:57:44

+1

是的,它是用手記事本++。然後粘貼它 – 2010-03-30 16:50:08

回答

0

我設法得到它的工作通過執行以下操作:

public class Case 
{ 
    public virtual int? Id { get; set; } 
    public virtual CaseReferral Referral { get; set; } 
} 
public class CaseReferral 
{ 
    public virtual string Type { get; protected set; } 
    public virtual int? ReferralId { get; protected set; } 
    public virtual string Name { get { return null; } 

    //NOTE: We need this for mapping reasons 
    protected virtual int CaseId { get; set; } 
    protected CaseReferral() { } 
} 

public class CaseSourceAReferral : CaseReferral 
{ 
    private SourceA _sourceA; 
    public virtual SourceA Source 
    { 
    get { return _sourceA; } 
    protected set 
    { 
     _sourceA = value; 

     Type = "SourceA"; 
     ReferralId = (_sourceA != null ? _sourceA.Id : null); 
    } 
    } 

    public override string Name { get { return Source.Name; } } 

    //NOTE: Default constructor for mapping reasons 
    protected CaseSourceAReferral() { } 
    public CaseSourceAReferral(int caseId, SourceA source) 
    { 
    CaseId = caseId; 
    Source = source; 
    } 
} 

public class CaseMap : ClassMap<Case> 
{ 
    public CaseMap() 
    { 
    Id(c => c.Id); 
    References(c => c.Referral).Column("Id"); 
    } 
} 

public class CaseReferralMap : ClassMap<CaseReferral> 
{ 
    public CaseReferralMap() 
    { 
    Id(Reveal.Property<CaseReferral>("CaseId")).Column("Id"); 
    Map(r => r.Type).Column("ReferralType"); 
    Map(r => r.ReferralId).Column("ReferralId"); 
    DiscriminateSubClassesOnColumn("ReferralType"); 
    } 
} 

public class CaseSourceAReferralMap : SubclassMap<CaseSourceAReferral> 
{ 
    public CaseSourceAReferralMap() 
    { 
    DiscriminatorValue("SourceA"); 
    References(r => r.Source).Column("ReferralId"); 
    } 
} 
0

許多到任何
如果表結構是固定的,並且要使用identity id生成器,我將映射源表作爲3個獨立的類並映射到通用接口,作爲any參考。

class Case 
{ 
    public virtual IReferral Referral { get; set; } 
} 

class SourceA : IReferral 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Type { get { return "SourceA"; } } 
} 

interface IReferral 
{ 
    int Id { get; set; } 
    string Name { get; set; } 
    string Type { get; } 
} 

public class CaseMap : ClassMap<Case> 
{ 
    public CaseMap() 
    { 
     ReferencesAny(m => m.Referral) 
      .EntityTypeColumn("ReferralType") 
      .EntityIdentifierColumn("ReferralId") 
      .AddMetaValue<SourceA>("SourceA") 
      .AddMetaValue<SourceB>("SourceB") 
      .AddMetaValue<SourceC>("SourceC") 
      .IdentityType<int>(); 
    } 
} 

工會子類
另一種選擇是union-subclass與一個抽象基類的映射。這允許提前獲取,但不能在子類表上使用identity生成器。

<class name="IReferral" abstract="true" table="Referral"> 
    <id name="Id"> 
     <generator class="hilo"/> 
    </id> 
    <property name="Name"/> 
    <union-subclass name="SourceA" table="SourceA"> 
     <!-- class specific properties --> 
    </union-subclass> 
    <union-subclass name="SourceB" table="SourceB"> 
     <!-- class specific properties --> 
    </union-subclass> 
    <union-subclass name="SourceC" table="SourceC"> 
     <!-- class specific properties --> 
    </union-subclass> 
</class> 


如果你可以改變的表,可以將所有3個介類映射到使用subclass同桌。

<class name="IReferral" abstract="true" table="Referral" discriminator-value="null"> 
    <id name="Id"> 
     <generator class="identity"/> 
    </id> 
    <discriminator column="Discriminator" not-null="true" type="System.String"/> 
    <property name="Name"/> 
    <subclass name="SourceA" discriminator-value="SourceA"> 
     <!-- class specific properties --> 
    </subclass> 
    <subclass name="SourceB" discriminator-value="SourceB"> 
     <!-- class specific properties --> 
    </subclass> 
    <subclass name="SourceC" discriminator-value="SourceC"> 
     <!-- class specific properties --> 
    </subclass> 
</class> 
+0

我似乎無法讓您的示例工作。我得到「不是成員訪問 參數名稱:表達式」錯誤 – 2010-03-17 03:03:06

+0

我設法使它工作(請參閱我的答案)。感謝Lachlan的幫助。 – 2010-03-17 16:19:47