Say I have the following (simplified):
public class Item
{
public String Name { get; set; }
public String Type { get; set; }
}
public class Armor : Item
{
public int AC { get; set; }
public Armor () { Type = "Armor"; }
}
public class Weapon : Item
{
public int Damage { get; set; }
public Armor () { Type = "Weapon"; }
}
public class Actor
{
...
}
public class HasItem : Relationship<ItemProps>, IRelationshipAllowingSourceNode<Actor>, IRelationshipAllowingTargetNode<Item>
{
public readonly string TypeKey = "HasItem";
public HasItem ( NodeReference targetItem, int count = 1 )
: base(targetItem, new ItemProps { Count = count })
{
}
public override string RelationshipTypeKey
{
get { return TypeKey; }
}
}
With this setup I can easily create a heterogeneous list of Weapons, Armor, etc related to the Actor. But I can't seem to figure out how to get them out. I have this method (again simplified) to get a list of all the related items, but it gets them all out as Items. I can't figure out how to get them as their actual type. I can use the Type field to determine the type, but there doesn't seem to be anyway of dynamically building the return:
public IEnumerable<Item> Items
{
get
{
return
GameNode
.GraphClient
.Cypher
.Start(new { a = Node.ByIndexLookup("node_auto_index", "Name", Name) })
.Match("(a)-[r:HasItem]-(i)")
.Return<Item>("i") // Need something here to return Armor, Weapon, etc as needed based on the Type property
.Results;
}
}
I found a bad workaround where I return the Type and NodeID and run the list through a switch statement that does a .Get with the NodeID and casts it to the right type. but this is inflexible and inefficient. I could run one query for each derived class and concatenate them together, but the thought of that makes my skin crawl.
This seems like it would be a common problem, but I couldn't find anything online. Any ideas?