2008-11-17 9 views
7

Giả sử tôi có ba lớp. Nó là hợp lệ để khởi tạo A, nhưng cũng có trường hợp đặc biệt B và D mà lớp con A, thêm thông tin bổ sung.Lưu loát NHibernate - cách ánh xạ một phân lớp một-một?

Làm cách nào để tạo các tệp ánh xạ cho NHibernate này (thông thạo)?

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 
} 

tôi đã cố gắng điều sau đây, nhưng nó không hoạt động tại tất cả:

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

Trả lời

7

Tôi không chắc tôi hiểu những gì bạn có ý nghĩa bởi "bản đồ một lớp con one-to-one", nhưng nếu bạn muốn ánh xạ thừa kế mà lớp con có tính năng mà không nullable, bạn có thể làm như thế này trong thạo-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(); 
    } 
} 

Vì bạn muốn tài sản của lớp con là không rỗng, bạn phải sử dụng bảng mỗi lớp (tham gia-subclass) cách mô hình hóa thừa kế. Điều này là do bảng mỗi phân cấp yêu cầu tất cả các thuộc tính lớp con phải có giá trị rỗng.

Tôi hy vọng điều đó sẽ hữu ích.

/Erik

+0

Erik, great post. – Berryl

5

Cú pháp có thể đã thay đổi trong FNH từ bài đăng của Erik, nhưng ví dụ của anh ấy đúng về đích. Dưới đây là một số mã tôi sử dụng dựa trên bài viết của Erik để làm việc thông qua FNH hai chiến lược lớp con FNH mà tôi biết ngay bây giờ (SubClass (mã nhận xét bên dưới và JoinSubClass). cùng một chiến lược, bao gồm trong tài liệu NHibernate, có một chút khó hiểu khi điều này mới mẻ với bạn. (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); 
     }; 
    } 
}