Following on from my last post here’s what I found and how I used the package at http://www.ayende.com/projects/nhibernate-query-analyzer/downloads.aspx for generics in NHibernate 1.0.2 and 1-many type relationship mappings:
Your variables need to follow a particular naming notation (otherwise it will complain that it cant find it). This can be overridden but I found it was just easier to make sure that your classes followed the default expected notation which is: underscore followed by a small letter followed by anything else eg: _oTeam, _riders etc would be valid member variables – _OTeam, m_riders etc would be invalid. Pretty simple since thats probibly the notation most people use anyway but it is something to watch out for 🙂 There are two classes you should know about to just get something running with generics at the very minimum. EntityRef of T and EntityList of T. At one end of the relationship you will have the collection (in the example this is in the Team class and the collection is of type Rider), In the team class we have something like:
private EntityList _riders;
and in the default constructor you would have:
public Team()
{
_riders = new EntityList(
delegate(Rider o) { o.OTeam = this; },
delegate(Rider o) { o.OTeam = null; });
}
The first part of the delegate is what happens when a rider is added to the teams riders collection (links it up) while the second part is when the rider is removed from the teams riders collection (breaks the link). So now you dont need to do any special linking code in other methods – you can get rid of those .AddX methods 🙂 (I hadnt thought about using this so I was like – oh yeah – good thinking 🙂 )
You need to use delegates in the default constructor to setup the adding / removing functionality for the collections – once you start using them you get to understand what is going on but at the start you may be like – say what? If you have any other constructors then just use a : this() to make sure the default constructor is called and all these delegates are setup each time 🙂
The attribute markup for the collection would be (note the Access attribute and lack of setter):
[NHMA.Bag(0, Lazy = true,
Inverse = true,
Cascade = NHMA.CascadeStyle.AllDeleteOrphan,
Access = “NHibernate.Generics.GenericAccessor, NHibernate.Generics”,
Name = “Riders”)]
[NHMA.Key(1, Column = “TeamID”)]
[NHMA.OneToMany(2, ClassType = typeof(Rider))]
public IList Riders
{
get { return _riders; }
}
In the riders class we need the other part of the link. This is where the EntityRef comes in.
private EntityRef _oTeam;
In the Rider constructor we also need to setup some delegates (note the Add/Remove):
public Rider()
{
_oTeam = new EntityRef(
delegate(Team o) { o.Riders.Add(this); },
delegate(Team o) { o.Riders.Remove(this); }
);
}
and then finally the attribute markup for the team would be something like the following (note the .Value, the type – Team not EntityRef, and the Access attribute):
[NHMA.ManyToOne( Name = “OTeam”,
Access = “NHibernate.Generics.GenericAccessor, NHibernate.Generics”,
Column = “TeamID”,
NotNull = true,
ClassType = typeof(Team) )]
public Team OTeam
{
get { return _oTeam.Value; }
set { _oTeam.Value = value; }
}
So as you can see – a few tricks to get this one working but it does work – just reference the dll and away you go. Should keep fill the gap while the NHibernate 2.0 effort is underway 🙂 The source code and the tests/examples at the svc source are a good place to start to see what is available and how something is done. If you havent got an svc client then a good one can be found here : http://tortoisesvn.tigris.org/ (thanks JD!)