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