等效于NHibernate IStatelessSession的Load方法



我正在使用NHibernate将行大容量插入数据库。由于我插入的数据量很大,所以我使用IStatelessSession而不是ISession。我插入的对象使用指定的标识(即没有生成hilo或guid——唯一的id被分配给对象)。

我的问题是,我有一个对象(比如Foo),它有一个对另一个对象的多对一引用(比如Bar)。我先插入所有的Bar对象,这没有问题。

当我想要插入Foo对象时,问题就出现了。我知道每个Bar对象的唯一标识符,但我不想在插入之前必须从数据库中检索每个Bar对象来设置Foo对象的属性。

现在可能是展示一个简单示例的好时机:

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; }
}

假设我想创建一个Id为(比如)1234的新Foo对象,该对象引用一个Id为(比如说)4567的Bar对象。我知道已经有一个具有此标识符的Bar对象,因为我之前已经添加了所有的Bar对象。

如何添加Foo对象而不必再次从数据库中检索Bar对象?

奇怪的是,有时如果你花时间制定问题,你很快就会意识到答案。

您所做的是创建一个对象,该对象具有Id,而没有其他设置。

步骤1:插入条形对象

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();
    }
}

第2步:插入带有伪Bar对象的Foo对象

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();
    }
}

但是,如果有人有更好的方法(例如,不需要创建大量虚拟对象),我将感谢你的建议。

插入Bar对象并将引用分配给正确的Bar对象后,将它们存储在Dictionary<int, Bar>中:

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

您的解决方案也可以工作,但需要Bar.Id.的公共设置器

您可以使用会话。Get(id),如果会话具有Bar的entityies,它将返回一个代理,并且您将通过代理引用创建Foo对象,而不需要任何对数据库的调用。

这确实NOT访问数据库,并且是一种填充外键而不必加载实体的方法。

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

忽略。

最新更新