7

假设我有三个班级。实例化 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<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();
    }
}
4

2 回答 2

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

由于您希望子类的属性不为空,因此您必须使用 table-per-class (joined-subclass) 方式对继承进行建模。这是因为每个层次结构的表要求所有子类属性都可以为空。

我希望它有所帮助。

/埃里克

于 2008-11-18T10:08:03.650 回答
5

自 Erik 的帖子以来,FNH 中的语法可能已经改变,但他的示例是正确的。这是我根据 Erik 的帖子使用的一些代码,用于处理我现在知道的两个 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);
        };
    }
}
于 2009-07-23T12:39:17.217 回答