0

Voici mes classes appropriées:collection inhabituelle NHibernate/cartographie héritage

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

Et voici les pièces cartographiques pertinentes:

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

L'espoir tout est clair jusqu'à présent. Ce que j'essaie de faire est la suivante: lorsque je sélectionne mes objets Section, je veux qu'ils ne contiennent que des objets "légers" ArticleMetadata. Mais lors de l'enregistrement Section à la DB, je veux NHibernate persister Article objets ainsi:

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

session.SaveOrUpdate(section); 

Actuellement, SaveOrUpdate sortie sans erreur que ce soit, mais un objet Article complet est enregistré que partiellement. En d'autres termes, la valeur de sa propriété Content ne parvient jamais à la base de données.

Enregistrement Article séparément (session.Save(new Article(...));) fonctionne comme prévu, en enregistrant toutes les propriétés mappées. En résumé: Je souhaite ajouter à la fois les objets ArticleMetadata et Article à la collection Section.Articles, et je souhaite qu'ils soient enregistrés correctement. Ce genre de comportement est-il possible?

Répondre

3

Je sais que ce n'est pas une solution directe à votre problème (je ne pense pas que ce que vous faites peut fonctionner sans le mappage d'héritage, et ensuite vous avez le clob chargé aussi). Une façon de faire ce que vous voulez, c'est de faire de Content une propriété chargée paresseuse, et de laisser tomber l'héritage.

Plus sur les propriétés chargées paresseuses peuvent être trouvés ici: http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx

Une autre façon est d'avoir deux collections, l'une pour les articles et un pour ArticleMetadata.

0

Je pense que vous aurez besoin de maintenir explicitement les objets-objets afin de les faire fonctionner. Je suppose que la section-cascade les traite comme ArticleMetadata et, par conséquent, les stocker en tant que tels. Dans le cas contraire, si vous ne spécifiez pas de cascade, et que vous utilisez plutôt session.Create (new Article()), le mécanisme de vidage s'en chargera peut-être pour vous. La cascade n'est utile que si vous ne créez pas explicitement les objets afaik.

Un pointeur cependant. Afin de ne pas charger un article complet lorsque vous sélectionnez ArticleMetadata, vous devez spécifier polymorphism = "explicit" sur votre mapping de classe sur ArticleMetadata, sinon il identifiera l'héritage et sélectionnera votre article sur une requête séparée à chaque fois.