等效于NHibernate IStatelessSession的Load方法
本文关键字:Load 方法 IStatelessSession NHibernate | 更新日期: 2023-09-27 18:28:42
我正在使用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)
};
忽略。