简体   繁体   中英

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?

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.

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.

你可以使用session.Get(id),如果会话有Bar的实体,它返回一个代理,你将通过代理引用创建Foo对象,而不需要调用DataBase。

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM