Equivalent of Load method for NHibernate IStatelessSession

1.4k Views Asked by At

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?

4

There are 4 best solutions below

0
John Jeffery On BEST ANSWER

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.

2
Anton On

You can use session.Get(id), if the session has got Bar's entityies, it return a proxy, and you'll create Foo object by proxy reference without any call to the DataBase.

2
Rippo On

This does NOT make a trip to the the database and is a way to populate the foreign-key without having to load the entity.

var foo = new Foo
{
  Id = 4567,
  Bar = new Session.Get<Bar>(1234)
};

Ignore.

7
Jamie Ide On

Store the Bar objects in a Dictionary<int, Bar> after you insert them and assign the reference to the correct Bar object:

var foo = new Foo();
foo.Bar = bars[1234];
session.Save(foo); // there is no session.Insert method

You solution works too but requires a public setter for Bar.Id.