开发者

Fluent NHibermate and Polymorphism and a Newbie!

开发者 https://www.devze.com 2023-01-02 19:48 出处:网络
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 applicatio

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 typ开发者_开发百科es 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.


As it stands, the BundleItem1 and BundleItem2 properties will always have a Product proxy because NH creates your proxies without touching the database, so it doesn't know if they are Products or some derived type. But when you call a method on your bundle items, NH should hit the DB and load the correct record, and you should get polymorphic behavior.

You could test this out. Add an override of ToString to your SizedProduct:

public override string ToString()
{
   return "I'm a sized product!";
}

Then load your BundleProduct and do this:

Debug.WriteLine(bp.BundleItem1.ToString());
Debug.WriteLine(bp.BundleItem2.ToString());

You should find that the second call prints out "I'm a sized product!", and this will demonstrate that you have working polymorphism.

Assuming this all worked as I've described, its time to tackle the real question: what exactly do you want to do? Maybe you could provide some code that doesn't actually work as you would like it to.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号