Search code examples
c#nhibernateistatelesssession

Equivalent of Load method for NHibernate IStatelessSession


I am using NHibernate to bulk-insert rows into my database. Because of the amount of data I am inserting, I am using IStatelessSession instead of ISession. The objects I am inserting use assigned identities (ie no hilo or guids generated -- the unique ids are assigned to the objects).

My problem is that I have an object (say Foo) which has a many-to-one reference to another object (say Bar). I insert all of the Bar objects first and that is no problem.

The problem comes when I want to insert the Foo objects. I know the unique identifier of each Bar object, but I don't want to have to retrieve each Bar object from the database in order to set the property on the Foo object before inserting it.

Now might be a good time to show a simple example:

public class Foo {
    // Unique identifier (assigned)
    public virtual int Id { get; set; }

    // Many-to-one reference to a Bar object
    public virtual Bar Bar { get; set; }
}

public class Bar {
    // Unique identifier (assigned)
    public virtual int Id { get; set; }
}

Let's say that I want to create a new Foo object with an Id of (say) 1234 that references a Bar object that has an Id of (say) 4567. I know that there is already a Bar object with this identifier because I have added all the Bar objects previously.

How do I go about adding the Foo object without having to retrieve the Bar object from the database again?


Solution

  • Strange that sometimes if you take the time to formulate your question, you realise the answer shortly after.

    What you do is create a dummy object that has the Id and nothing else set.

    STEP 1: Insert the Bar Object

    using (var session = SessionFactory.OpenStatelessSession())
    {
        using (var tx = session.BeginTransaction())
        {
            var bar = new Bar
            {
                Id = 1234,
                // and populate all of the other
                // properties that you would put here
            };
            session.Insert(bar);
            tx.Commit();
        }
    }
    

    STEP 2: Insert the Foo Object with a dummy Bar object

    using (var session = SessionFactory.OpenStatelessSession())
    {
        using (var tx = session.BeginTransaction())
        {
            var foo = new Foo
            {
                Id = 4567,
                // dummy Bar object that has an Id and nothing else
                Bar = new Bar {Id = 1234}
            };
            session.Insert(foo);
            tx.Commit();
        }
    }
    

    But if anyone has a better way (for example, that does not require creating lots of dummy objects), I'd be grateful for advice.