3

我正在使用 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; }
}

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

如何在不必再次从数据库Foo中检索对象的情况下添加对象Bar

4

4 回答 4

4

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

您所做的是创建一个具有 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();
    }
}

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

于 2012-03-21T08:40:25.353 回答
2

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

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

您的解决方案也有效,但需要 Bar.Id 的公共设置器。

于 2012-03-21T13:20:18.153 回答
0

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

于 2012-03-21T09:49:55.860 回答
0

这不会访问数据库,并且是一种无需加载实体即可填充外键的方法。

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

忽视。

于 2012-03-21T11:23:36.050 回答