2008-11-17 10 views
7

Supongamos que tengo tres clases. Es válido para crear instancias de A, pero también hay casos especiales B y D, cuya subclase A agrega información adicional.Fluidez NHibernate: ¿cómo asignar una subclase uno a uno?

¿Cómo puedo hacer los archivos de mapeo para esto en (con fluidez) 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 
} 

He intentado lo siguiente, pero no funciona en absoluto:

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(); 
    } 
} 

Respuesta

7

No estoy seguro de entender lo que quiere decir con "mapear una subclase uno-a-uno", pero si desea asignar la herencia donde las subclases tienen propiedades que no son anulables, puede hacerlo así en Fluido-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(); 
    } 
} 

Puesto que desea propiedades de las subclases ser no nulo, lo que tiene que usa la tabla por clase (mixed-subclass) forma de modelar la herencia. Esto se debe a que la tabla por jerarquía requiere que todas las propiedades de las subclas sean anulables.

Espero que ayude.

/Erik

+0

Erik, gran post. – Berryl

5

La sintaxis puede haber cambiado en FNH desde el puesto de Erik, pero su ejemplo es justo en el blanco. Aquí hay un código que utilicé basado en la publicación de Erik para trabajar a través de FNH las dos estrategias de subclase FNH que conozco en este momento (SubClass (el código comentado a continuación, y JoinedSubClass). Como comentario adicional, he visto otros nombres usados ​​para describir el mismas estrategias, incluso en documentos de NHibernate, que es un poco confuso cuando esto es nuevo para usted. (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); 
     }; 
    } 
} 
Cuestiones relacionadas