Fluent NHibermate and Polymorphism and a Newbie!

Posted by Andy Baker on Stack Overflow See other posts from Stack Overflow or by Andy Baker
Published on 2010-06-04T11:31:35Z Indexed on 2010/06/05 12:22 UTC
Read the original article Hit count: 419

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.

© Stack Overflow or respective owner

Related posts about fluent-nhibernate

Related posts about nhibernate-mapping