Fluent NHibermate and Polymorphism and a Newbie!
- by Andy Baker
I'm a fluent nhibernate newbie and I'm struggling mapping a hierarchy of polymorhophic objects. I've produced the following Model that recreates the essence of what I'm doing in my real application.
I have a ProductList and several specialised type of products;
public class MyProductList
{
public virtual int Id { get; set; }
public virtual string Name {get;set;}
public virtual IList<Product> Products { get; set; }
public MyProductList()
{
Products = new List<Product>();
}
}
public class Product
{
public virtual int Id { get; set; }
public virtual string ProductDescription {get;set;}
}
public class SizedProduct : Product
{
public virtual decimal Size {get;set;}
}
public class BundleProduct : Product
{
public virtual Product BundleItem1 {get;set;}
public virtual Product BundleItem2 {get;set;}
}
Note that I have a specialised type of Product called BundleProduct that has two products attached.
I can add any of the specialised types of product to MyProductList and a bundle Product can be made up of any of the specialised types of product too.
Here is the fluent nhibernate mapping that I'm using;
public class MyListMap : ClassMap<MyList>
{
public MyListMap()
{
Id(ml => ml.Id);
Map(ml => ml.Name);
HasManyToMany(ml => ml.Products).Cascade.All();
}
}
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Id(prod => prod.Id);
Map(prod => prod.ProductDescription);
}
}
public class SizedProductMap : SubclassMap<SizedProduct>
{
public SizedProductMap()
{
Map(sp => sp.Size);
}
}
public class BundleProductMap : SubclassMap<BundleProduct>
{
public BundleProductMap()
{
References(bp => bp.BundleItem1).Cascade.All();
References(bp => bp.BundleItem2).Cascade.All();
}
}
I haven't configured have any reverse mappings, so a product doesn't know which Lists it belongs to or which bundles it is part of.
Next I add some products to my list;
MyList ml = new MyList() { Name = "Example" };
ml.Products.Add(new Product() { ProductDescription = "PSU" });
ml.Products.Add(new SizedProduct() { ProductDescription = "Extension Cable", Size = 2.0M });
ml.Products.Add(new BundleProduct()
{
ProductDescription = "Fan & Cable",
BundleItem1 = new Product() { ProductDescription = "Fan Power Cable" },
BundleItem2 = new SizedProduct() { ProductDescription = "80mm Fan", Size = 80M }
});
When I persist my list to the database and reload it, the list itself contains the items I expect ie MyList[0] has a type of Product, MyList[1] has a type of SizedProduct, and MyList[2] has a type of BundleProduct - great!
If I navigate to the BundleProduct, I'm not able to see the types of Product attached to the BundleItem1 or BundleItem2 instead they are always proxies to the Product - in this example BundleItem2 should be a SizedProduct.
Is there anything I can do to resove this either in my model or the mapping?
Thanks in advance for your help.