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
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"}
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.