Entities:
—————————————————————————–
public class Order
{
public int OrderID { get; set; }
public string CustomerID { get; set; }
public Shipper ShipVia { get; set; }
}
public class Shipper : ILifecycle
{
public int ShipperID { get; set; }
public string CompanyName { get; set; }
public string Phone { get; set; }
#region ILifecycle Members
public LifecycleVeto OnDelete(NHibernate.ISession s)
{
throw new NotImplementedException();
}
public void OnLoad(NHibernate.ISession s, object id)
{
}
public LifecycleVeto OnSave(NHibernate.ISession s)
{
throw new NotImplementedException();
}
public LifecycleVeto OnUpdate(NHibernate.ISession s)
{
throw new NotImplementedException();
}
#endregion
}
—————————————————————————–
And finally the SQL function:
—————————————————————————–
ALTER FUNCTION dbo.GetShipper(@shipperId int)
RETURNS int
AS
BEGIN
RETURN @shipperId
END
—————————————————————————–
Obviously, you’ll want the function to do something meaningful, but the idea is you return the PK for the entity.
As it turns out specifying the property type is not enough, we have to do something else to get the NHibernate to recognize our type. That came as surprise for me, considering documentation makes no mention of it.
I had to step through the NHibernate code to see that it tried to obtain an instance of IType given our type name.
First path I tried was making the class [Serializable], as I recall that our types at the project where it "just worked for me" were all [Serializable]. In short – It doesn’t work.
The trick it turned out is in ILifecycle interface. We had that interface implemented from the earlier days of NHibernate.
Today the interface is considered too intrusive (which it is) and judging from the NHibernate source code, nothing better has been implemented. So I think it’s a bug, or at least something that should be mentioned in the documentation explicitly.
Anyways, as you can see implementation of ILifecycle can be trivial, you just have to make sure you don’t veto anything. So if you don’t mind getting your domain model "dirty" that’s the simpliest way to get it working.