2008-11-17 137 views
7

假設我有三個類。實例化A是有效的,但是也存在特殊情況B和D,它們是A的子類,增加了額外的信息。流利的NHibernate - 如何映射一個子類的一對一?

我該如何做(流利的)NHibernate的映射文件?

public class A 
{ 
    public int ID { get; set;} 
    public string CommonProperty1 { get; set; } 
    public string CommonProperty2 { get; set; } 
} 

public class B : A 
{ 
    public string BSpecificProperty1 { get; set; } //not null 
    public string BSpecificProperty2 { get; set; } //not null 
} 

public class D : A 
{ 
    public string DSpecificProperty { get; set; } //not null 
} 

我嘗試以下,但它並沒有在所有的工作:

public class AMap : ClassMap<A> 
{ 
    public AMap() 
    { 
     Id(x => x.ID); 

     Map(x => x.CommonProperty1); 
     Map(x => x.CommonProperty2); 
    } 
} 

public class BMap : ClassMap<B> 
{ 
    public BMap() 
    { 
     References(x => x.ID); 
     Map(x => x.BSpecificProperty1) 
      .CanNotBeNull(); 
     Map(x => x.BSpecificProperty2) 
      .CanNotBeNull(); 
    } 
} 

public class DMap : ClassMap<D> 
{ 
    public DMap() 
    { 
     References(x => x.ID); 

     Map(x => x.DSpecificProperty) 
      .CanNotBeNull(); 
    } 
} 

回答

7

我不知道我理解你所說的「映射的子類一到一個」的意思,但如果你想映射繼承在子類中有沒有空的屬性,你可以這樣做的流利,NHibernate的:

// Domain classes 
public class Animal 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

public class Cat : Animal 
{ 
    public virtual int WhiskerLength { get; set; } 
    public virtual int ClawCount { get; set; } 
} 

public class Dog : Animal 
{ 
    public virtual int TailWagRate { get; set; } 
} 



// Mapping file 
public class AnimalMap : ClassMap<Animal> 
{ 
    public AnimalMap() 
    { 
     Id(x => x.Id) 
      .WithUnsavedValue(0) 
      .GeneratedBy.Native(); 

     Map(x => x.Name); 

     var catMap = JoinedSubClass<Cat>("CatId", sm => sm.Map(x => x.Id)); 

     catMap.Map(x => x.WhiskerLength) 
      .CanNotBeNull(); 
     catMap.Map(x => x.ClawCount) 
      .CanNotBeNull(); 

     JoinedSubClass<Dog>("DogId", sm => sm.Map(x => x.Id)) 
      .Map(x => x.TailWagRate) 
       .CanNotBeNull(); 
    } 
} 

既然你想要的子類的屬性,看看是不是空的,你必須使用每班的表格(連接子類)的繼承建模方式。這是因爲table-per-hierarchy要求所有的子類屬性都是可空的。

我希望它有幫助。

/埃裏克

+0

埃裏克,偉大的職位。 – Berryl 2009-07-23 12:39:00

5

的語法可能在FNH因爲Erik的職位變了,但他的例子是正確的目標。下面是我使用的一些代碼,基於Erik的帖子,通過FNH介紹了我現在知道的兩個FNH子類策略(SubClass(下面註釋掉的代碼和JoinedSubClass)。另外,我已經看到用於描述同樣的戰略,包括在NHibernate的文檔,這是一個有點混亂時,這是新的給你。(https://www.hibernate.org/hib_docs/nhibernate/html/inheritance.html)。

// Domain classes 
public class Animal : Entity 
{ 
    public virtual string Name { get; set; } 
    public virtual string Unwanted { get; set; } 
} 

public class Cat : Animal 
{ 
    public virtual int WhiskerLength { get; set; } 
    public virtual int ClawCount { get; set; } 
} 

public class Dog : Animal 
{ 
    public virtual int TailWagRate { get; set; } 
} 

public class Boxer : Dog 
{ 
    public string DroolBucket { get; set; } 
} 

public class AnimalMapJoinedSubclassOverride : IAutoMappingOverride<Animal> 
{ 
    public void Override(AutoMap<Animal> mapping) { 
     mapping.Map(x => x.Name); 

     mapping.IgnoreProperty(x => x.Unwanted); 

     mapping.JoinedSubClass("CatId", CatMap.AsJoinedSubClass()); 
     mapping.JoinedSubClass("DogId", DogMap.AsJoinedSubClass()); 
     //mapping.DiscriminateSubClassesOnColumn("Type") 
     // .SubClass<Cat>("CatId", CatMap.AsSubClass()) 
     // .SubClass<Dog>("CatId", DogMap.AsSubClass()); 
    } 
} 

public class CatMap 
{ 
    public static Action<JoinedSubClassPart<Cat>> AsJoinedSubClass() 
    { 
     return part => 
     { 
      part.Map(x => x.ClawCount).Not.Nullable(); 
      part.Map(x => x.WhiskerLength).Not.Nullable(); 
     }; 
    } 

    public static Action<SubClassPart<Cat>> AsSubClass() 
    { 
     return part => 
     { 
      part.Map(x => x.ClawCount); 
      part.Map(x => x.WhiskerLength); 
     }; 
    } 
} 

public class DogMap 
{ 
    public static Action<JoinedSubClassPart<Dog>> AsJoinedSubClass() 
    { 
     return sub => 
     { 
      sub.Map(x => x.TailWagRate).Not.Nullable(); 
     }; 
    } 

    public static Action<SubClassPart<Dog>> AsSubClass() 
    { 
     return sub => 
     { 
      sub.Map(x => x.TailWagRate); 
     }; 
    } 
} 

public class BoxerMap 
{ 
    public static Action<JoinedSubClassPart<Boxer>> AsJoinedSubClass() 
    { 
     return sub => 
     { 
      sub.Map(x => x.DroolBucket); 
     }; 
    } 

    public static Action<SubClassPart<Boxer>> AsSubClass() 
    { 
     return sub => 
     { 
      sub.Map(x => x.DroolBucket); 
     }; 
    } 
}