views:

103

answers:

2

I have tried various approaches to mapping the following structure, but I finally admit that after a day of not getting very far, I need some help.

So the question is, how would you guys go about mapping something like this. The schema is not fixed at this point.

public abstract class BaseObject
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual string Prefix { get; set; }
    public virtual string Suffix { get; set; }
    public virtual BaseObject Parent { get; set; }
}

public class Room : BaseObject
{
    public virtual int AreaId { get; set; }

}

public class Item : BaseObject
{
    public virtual string Owner { get; set; }
    public virtual IList<ItemAttribute> Attributes { get; set; }
    public virtual int ItemTypeId { get; set; }

}

public class Potion : Item
{
    public virtual int AmountLeft { get; set; }
}

Your input is very much appreciated.

A: 

I would probably have a table for each class - Room, Item, Potion and then do fairly standard mappings for each.

I'd like to note that in my own experiences, it is a bad idea to name your Id field in your business objects "Id"

Here's a sample with Item, assoming some data names for your table.

public class ItemMap : ClassMap<Item>
    {
        public ItemMap()
        {
            WithTable("Items");

            Id(x => x.Id, "ItemId").GeneratedBy.Identity();

            Map(x => x.Name);
            Map(x => x.Description);
            Map(x => x.Prefix);
            Map(x => x.Suffix);
            Map(x => x.Owner);
            Map(x => x.ItemTypeId);

            References<Item>(x => x.Parent, "ParentItemId");

            HasManyToMany(x => x.Attributes)
                 .WithParentKeyColumn("ItemId")
                 .WithChildKeyColumn("AttributeId")
                 .WithTableName("ItemAttributes")
                 .LazyLoad();
        }
    }

This is more than likely not be perfect - as I'm not sure how the mapping will work with the abstract parent.

Josh
A: 

This allows you to have it all in one table... doing this from memory, so syntax might not be exact.

public class ItemMap : ClassMap<BaseObject>
{

...

   WithTable("objects");
    Id(x => x.Id).GeneratedBy.Identity();
    Map(x => x.Name);
    Map(x => x.Description);

    ...

    DiscriminateSubClassesOnColumn("Type")

      .SubClass<Room>("Room", x =>
                    {
                        x.Map(r => r.AreaId);
                    })

      .SubClass<Item>("Item", c =>
                                                {
                                                    i.Map(x => x.Owner);
                                                    i.References(x => x.Account).LazyLoad();
                                                    HasManyToMany(x => x.Attributes)
                                                      .WithParentKeyColumn("ItemId")
                                                      .WithChildKeyColumn("AttributeId")
                                                      .WithTableName("ItemAttributes")
                                                      .LazyLoad();    
                                                });

     .SubClass<Potion>("Potion", x =>
                    {
                        x.Map(p => p.AmountLeft);
                    })
mxmissile