当前位置:  开发笔记 > 编程语言 > 正文

流畅的NHibernate - 如何一对一地映射子类?

如何解决《流畅的NHibernate-如何一对一地映射子类?》经验,为你挑选了2个好方法。

假设我有三个班级.实例化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,因此必须使用每个类的表(连接子类)方式对继承进行建模.这是因为每个层次的表要求所有子类属性都可以为空.

我希望它有所帮助.

/埃里克



1> Erik Öjebo..:

我不确定我是通过"映射一对一的子类"来理解你的意思,但如果你想映射继承,其中子类具有不可为空的属性,你可以在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,因此必须使用每个类的表(连接子类)方式对继承进行建模.这是因为每个层次的表要求所有子类属性都可以为空.

我希望它有所帮助.

/埃里克



2> Berryl..:

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

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有