Question

I want to map one to many collection using nhibernate by code

..
   Bag(x => x.Articles,
     c => {  },
     r => { r.OneToMany(); }
   );

Articles is IList<IArticle> and lets say that I have concrete objects (MyArticle and MyArticle2) which implements IArticle.

Since I'm getting error {"Association references unmapped class: MyApp.Model.IArticle"} I suppose I have to list concrete types which I want to map.

How can I do this?

Update: To improve clarity I will further describe Article classes. There is

  • IArticle (interface)
  • ArticleBase (abstract class)
  • ArticleX
  • ArticleY
  • Article...

    public abstract class ArticleBase : Entity, IArticle { ... }

    public class ArticleX : ArticleBase
    {
       public IList<Image> Images {get; set;}
       ...
    }
    public class ArticleY : ArticleBase
    {
       public IList<Image> Images {get;set;}
       ...
    }
    

there is also Image class. Every article has bag of images and image has one to many relation to article.

public class Image : Entity<Guid>
{
   public virtual IArticle Article {get; set;}
}

**

Update 2

public class Image : Entity<Guid>
{
   public virtual ArticleBase Article { get; set; }
   public Image() { }
}

** I mapped using approach suggested bellow like this

public class ArticleBaseMap : ClassMapping<ArticleBase>
    {
        public ArticleBaseMap()
        {
            Id(x => x.Id, m => m.Generator(Generators.GuidComb));

            Discriminator(x =>
            {
                x.Column("discriminator");
            });
        }
    }

public class MyArticleMap : SubclassMapping<MyArticle>
{
    public MyArticle()
    {
        DiscriminatorValue("MyArticle");
    }
}

public class ImageMap : ClassMapping<Image>
{
    public ImageMap()
    {
        Id(x => x.Id, m => m.Generator(Generators.GuidComb));
        ManyToOne(x => x.Article, m =>
        {
            m.NotNullable(true);
            m.Class(typeof(ArticleBase));
        });
    }
}

I'm getting System.TypeInitializationException with message

{"Could not compile the mapping document: mapping_by_code"}
{"Cannot extend unmapped class: MyApp.Model.Article.MyArticle"}
Was it helpful?

Solution

This won't work in general. It could work only in case, that we've mapped the interface (acting as abstract class in fact) already, e.g.: 8.1.1. Table per class hierarchy, An example:

<class name="IArticle" table="Articles">
    ...
    <discriminator column="Discriminator" />
    <subclass name="Article1" discriminator-value="Article1">
    ...

The Mapping-by-Code - inheritance:

public class ArticleBaseMap : ClassMapping<IArticle>
{
    public ArticleBaseMap()
    {
        Discriminator(x =>
        {
            x.Column("discriminator");

subclasses:

public class Article1Map : SubclassMapping<Article1>
{
    public Article1Map()
    {
        DiscriminatorValue("Article1");
...

Such a mapped hierarchy should not throw "Association references unmapped" any more. So, the mapping in this case, will require the referenced interface or abstract/base class to be mapped - as hierarchy.

I would suggest, for clarity, to map the abstract class, to avoid confusion (that any implementation of IArticle can be added to that Bag). In fact, I do not see any advantage of mapping interfaces from the Buisness domain entities perspective.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top