不寻常的NHibernate集合/继承映射

时间:2010-08-03 11:17:48

标签: nhibernate nhibernate-collections nhibernate-inheritance

以下是我的相关课程:

public class ArticleMetadata
{
    public long ID { get; set; }

    public string Slug { get; set; }
}

public class Article : ArticleMetadata
{
    // This is a massive CLOB, hence separate class
    public string Content { get; set; }
}

public class Section
{
    public long ID { get; set; }

    public IList<ArticleMetadata> Articles { get; set; }
}

以下是相关的映射部分:

<class name="Article" table="Article">
</class>

<!-- Note that there's no explicit NHibernate inheritance mapping here -->
<class name="ArticleMetadata" table="Article">
</class>

<class name="Section" table="Section">  
    <bag name="Articles" cascade="all-delete-orphan" inverse="true" lazy="false">
        <key column="SectionID" />
        <one-to-many class="ArticleMetadata" />
    </bag>
</class>

希望直到现在都清楚。

我正在尝试做的事情如下:选择我的Section对象时,我希望它们只包含“轻量级”ArticleMetadata个对象。但是当将Section保存到数据库时,我希望NHibernate也能保留Article个对象:

var section = new Section();
section.Articles.Add(new ArticleMetadata("a1"));
section.Articles.Add(new Article("a2", "massive clob"));

session.SaveOrUpdate(section);

目前,SaveOrUpdate退出时没有任何错误,但是一个完整的Article对象只能部分保存。也就是说,它的'Content属性的值永远不会进入数据库。

单独保存Articlesession.Save(new Article(...));)按预期工作,保存所有映射的属性。

总结一下:我想将ArticleMetadataArticle个对象添加到Section.Articles集合中,并希望它们得到适当保存。这种行为是否可行?

2 个答案:

答案 0 :(得分:3)

我知道这不是你问题的直接解决方案(我不认为你所做的事情可以在没有继承映射的情况下工作,然后你也加载了clob。)

执行您想要的操作的一种方法是使Content成为延迟加载的属性,并删除继承。

有关延迟加载属性的更多信息,请访问:http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx

另一种方法是拥有两个集合,一个用于文章,一个用于ArticleMetadata。

答案 1 :(得分:0)

我认为你需要明确地持久化Article-objects才能让它们发挥作用。我假设Section-cascade将它们视为ArticleMetadata,因此将它们存储为。

否则,如果你没有指定级联,而是在它们上使用session.Create(new Article()),那么刷新机制可能会为你处理它。只有在未明确创建对象时,级联才有用。

虽然有一个指针。为了在选择ArticleMetadata时不加载完全成熟的文章,您必须在ArticleMetadata上的类映射上指定polymorphism =“explicit”,否则它将识别继承并每次在单独的查询上选择您的文章。