Search code examples
nhibernatenhibernate-mapping

NHibernate: Populate new entities relative properties with foreign key ID


I have structured my NHibernate models to hide the foreign key IDs as seems to be best practice, so instead of having both the relationship and the key modeled like this:

public class CompanyOffice
{
    public virtual int Id { get; set; }
    public virtual int CompanyId { get; set; }
    public virtual Company Company { get; set; }
}

I simply have:

public class CompanyOffice
{
    public virtual int Id { get; set; }
    public virtual Company Company { get; set; }
}

And let NHibernate take car of the rest. I like this, but I have a few tables with multiple foreign keys that need setting and when I create a new entity, in an MVC action, I'm having to do this:

public ActionResult CreateNewThing(int stuffId, int whatId, int blahId)
{
    var stuff = _service.GetStuffById(stuffId);
    var what = _service.GetWhatById(whatId);
    var blah = _service.GetBlahById(blahId);

    var thing = new Thing { Stuff = stuff, What = what, Blah = blah };
}

Which means three trips to the database to get the entities, when I don't really need them as I already have the IDs and could have just done:

var thing = new Thing { StuffId = stuffId, WhatId = whatId, BlahId = blahId };

Is there another way to achieve what I'm trying to do without hitting the database for the entities?
Should I just bite the bullet and map the foreign keys as well as the relationships?
Or am I being to concerned about the database trips and should I just crack on?


Solution

  • You are right to avoid mapping the FK Id, to avoid 3 addtional trips do this:-

    var thing = new Thing {
      Stuff = session.Load<Stuff>(20),
      What = session.Load<What>(21),
      Blah = session.Load<Blah>(2234),
    }
    

    session.Load is slightly different to session.Get

    Also it is worth noting that Thing.Stuff.Id also does not hit the database.

    This is a great post, I quote:-

    In session.load(), Hibernate will not hit the database (no select statement in output) to retrieve the Stock object, it will return a Stock proxy object – a fake object with given identify value. In this scenario, a proxy object is enough for to save a stock transaction record.