简体   繁体   English

异常的NHibernate集合/继承映射

[英]Unusual NHibernate collection/inheritance mapping

Here are my relevant classes: 这是我的相关课程:

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

And here are relevant mapping parts: 这里是相关的映射部分:

<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>

Hope it's all clear up until now. 希望到现在为止一切都已清除。

What I'm trying to do is as follows: when selecting my Section objects, I want them to contain only "lightweight" ArticleMetadata objects. 我想做的事情如下:在选择我的Section对象时,我希望它们仅包含“轻量级” ArticleMetadata对象。 But when saving Section to the DB, I want NHibernate to persist Article objects as well: 但是,当将Section保存到数据库时,我希望NHibernate也持久保存Article对象:

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

session.SaveOrUpdate(section);

Currently, SaveOrUpdate exit without any errors whatsoever, but a full-blown Article object gets saved only partially. 当前, SaveOrUpdate退出没有任何错误,但是一个成熟的Article对象仅被部分保存。 That is, value of its' Content property never makes it to the DB. 也就是说,其Content属性的值永远不会进入数据库。

Saving Article separately ( session.Save(new Article(...)); ) works as expected, saving all mapped properties. 单独保存Articlesession.Save(new Article(...)); )按预期工作,保存所有映射的属性。

To sum it up: I want to add both ArticleMetadata and Article objects to Section.Articles collection, and want them to be saved appropriately. 总结一下:我想将ArticleMetadataArticle对象都添加到Section.Articles集合中,并希望将它们适当地保存。 Is this kind of behavior possible at all? 这种行为有可能吗?

I know it isn't a direct solution to your problem (I don't think what you're doing can work without the inheritance mapping, and then you have the clob loaded too). 我知道这不是直接解决您的问题的方法(我认为如果没有继承映射,您正在做的事情就无法工作,然后您也加载了Clob)。

One way to do what it seems that you want, is to make Content a lazy loaded property, and drop the inheritance. 一种执行您想要的操作的方法是使Content成为延迟加载的属性,并删除继承。

More on lazy loaded properties can be found here: http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx 有关延迟加载的属性的更多信息,请参见: http : //ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx

Another way is to have two collections, one for Articles and one for ArticleMetadata. 另一种方法是拥有两个集合,一个用于Articles,一个用于ArticleMetadata。

I think you will need to persist Article-objects explicitly in order to get them to work. 我认为您将需要明确地保留Article-objects才能使其正常工作。 I assume the Section-cascade treats them as ArticleMetadata and hence, store them as such. 我假设Section-cascade将它们视为ArticleMetadata,因此将其存储为此类。

Otherwise, if you don't specify cascading, and use session.Create(new Article()) on them instead, then maybe the flush mechanism would take care of it for you. 否则,如果您不指定级联,而是在其上使用session.Create(new Article()),则刷新机制可能会为您处理。 Cascading is only useful if you don't explicitly create the objects afaik. 仅当您未显式创建对象afaik时,级联才有用。

One pointer though. 虽然一个指针。 In order to NOT load a fully blown Article when you select ArticleMetadata, you must specify polymorphism="explicit" on your class-mapping on ArticleMetadata, otherwise it will identify the inheritance and select your Article on a separate query every time. 为了在选择ArticleMetadata时不加载完整的Article,您必须在ArticleMetadata的类映射上指定polymorphism =“ explicit”,否则它将识别继承并每次在单独的查询中选择Article。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM