2008-11-17 2 views
7

Предположим, у меня есть три класса. Действителен для создания экземпляра A, но есть также специальные случаи B и D, которые являются подклассами A, добавляя дополнительную информацию.Fluent 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

Я не уверен, я понимаю, что вы имеете в виду «карта подкласса один-к-одному», но если вы хотите отобразить наследование, где подклассы имеют свойства, которые не обнуляемым, вы можете сделать, как это в Fluent-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(); 
    } 
} 

Поскольку вы хотите свойства подклассов быть не-NULL, вы должны используйте таблицу за класс (объединенный подкласс) способ моделирования наследования. Это связано с тем, что для каждой иерархии требуется, чтобы все свойства подкласса были нулевыми.

Надеюсь, это поможет.

/Erik

+0

Эрик, большой пост. – Berryl 2009-07-23 12:39:00

5

Синтаксис может быть изменен в FNH, так как пост Эрика, но его пример прямо на цель. Вот код, который я использовал на основании сообщения Эрика, чтобы работать через FNH две стратегии подкласса FNH, которые я знаю прямо сейчас (SubClass (прокомментированный код ниже и JoinSubClass). В стороне я видел другие имена, используемые для описания те же стратегии, в том числе в 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); 
     }; 
    } 
}