假设我有三个班级.实例化A是有效的,但也有特殊情况B和D,它们是A的子类,添加了额外的信息.
我如何在(流畅的)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 { public AMap() { Id(x => x.ID); Map(x => x.CommonProperty1); Map(x => x.CommonProperty2); } } public class BMap : ClassMap { public BMap() { References(x => x.ID); Map(x => x.BSpecificProperty1) .CanNotBeNull(); Map(x => x.BSpecificProperty2) .CanNotBeNull(); } } public class DMap : ClassMap{ public DMap() { References(x => x.ID); Map(x => x.DSpecificProperty) .CanNotBeNull(); } }
Erik Öjebo.. 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{ public AnimalMap() { Id(x => x.Id) .WithUnsavedValue(0) .GeneratedBy.Native(); Map(x => x.Name); var catMap = JoinedSubClass ("CatId", sm => sm.Map(x => x.Id)); catMap.Map(x => x.WhiskerLength) .CanNotBeNull(); catMap.Map(x => x.ClawCount) .CanNotBeNull(); JoinedSubClass ("DogId", sm => sm.Map(x => x.Id)) .Map(x => x.TailWagRate) .CanNotBeNull(); } }
由于您希望子类的属性不为null,因此必须使用每个类的表(连接子类)方式对继承进行建模.这是因为每个层次的表要求所有子类属性都可以为空.
我希望它有所帮助.
/埃里克
我不确定我是通过"映射一对一的子类"来理解你的意思,但如果你想映射继承,其中子类具有不可为空的属性,你可以在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{ public AnimalMap() { Id(x => x.Id) .WithUnsavedValue(0) .GeneratedBy.Native(); Map(x => x.Name); var catMap = JoinedSubClass ("CatId", sm => sm.Map(x => x.Id)); catMap.Map(x => x.WhiskerLength) .CanNotBeNull(); catMap.Map(x => x.ClawCount) .CanNotBeNull(); JoinedSubClass ("DogId", sm => sm.Map(x => x.Id)) .Map(x => x.TailWagRate) .CanNotBeNull(); } }
由于您希望子类的属性不为null,因此必须使用每个类的表(连接子类)方式对继承进行建模.这是因为每个层次的表要求所有子类属性都可以为空.
我希望它有所帮助.
/埃里克
自Erik的帖子以来,语法可能在FNH中发生了变化,但他的例子正好在目标上.以下是我根据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{ public void Override(AutoMap 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 ("CatId", CatMap.AsSubClass()) // .SubClass ("CatId", DogMap.AsSubClass()); } } public class CatMap { public static Action > AsJoinedSubClass() { return part => { part.Map(x => x.ClawCount).Not.Nullable(); part.Map(x => x.WhiskerLength).Not.Nullable(); }; } public static Action > AsSubClass() { return part => { part.Map(x => x.ClawCount); part.Map(x => x.WhiskerLength); }; } } public class DogMap { public static Action > AsJoinedSubClass() { return sub => { sub.Map(x => x.TailWagRate).Not.Nullable(); }; } public static Action > AsSubClass() { return sub => { sub.Map(x => x.TailWagRate); }; } } public class BoxerMap { public static Action > AsJoinedSubClass() { return sub => { sub.Map(x => x.DroolBucket); }; } public static Action > AsSubClass() { return sub => { sub.Map(x => x.DroolBucket); }; } }