NHibernate期货有时返回代理,有时返回实体

本文关键字:返回 实体 代理 NHibernate | 更新日期: 2023-09-27 18:09:47

我有一个数据库获取处理使用多个未来查询的完整对象图。它看起来像这样(类名已经被改变以保护无辜):

Foo foo;
var fooFuture = Session.QueryOver<Foo>()
                       .Where(f => f.Id == id)
                       .Future();
// load up the Blah collection for the Foo
Session.QueryOver<Foo>()
       .Fetch(f => f.Blahs).Eager
       .Where(f => f.Id == id)
       .Future();
// do a separate query for the BlahOptions -- this is needed
// because if we did a Join and Join off of Foo, we'd get duplicate Blah
// results and that's not good
Session.QueryOver<Blah>()
       .Fetch(b => b.Options).Eager
       .Where(b => b.Foo.Id == id)
       .Future();
// load up the Attributes for the Foo
Session.QueryOver<Foo>()
       .Fetch(f => f.Attributes).Eager
       .Where(f => f.Id == id)
       .Future();
foo = fooFuture.SingleOrDefault();

注意:我可以在NHibernate LINQ中实现这个,但是行为保持不变。

奇怪的是: foo有时是FooNamespace.Foo类型(正确的、具体的类型),而其他时候是Castle.Proxies.FooProxy类型。

我是否得到真正的类型或代理的类型似乎取决于是否在会话中使用了NHibernate。当这个查询发生在其他NHibernate查询之后,它返回一个FooProxy。如果这是第一次使用会话,它返回一个Foo

为什么会发生这种情况?我怎样才能防止它的发生?我有目的地抓取Foo的整个对象图,以确保没有代理。并且图形本身不包含任何代理,它只是根Foo引用。事实上,返回类型取决于NHibernate之前做了什么,这似乎是关键(而且真的很奇怪)。

结束语:

  • NHibernateUtil.IsInitialized在输入FooProxy时返回true,所以我不能保证它不是那样的代理
  • 我是代理不利的,因为图形将被序列化用于缓存目的,反序列化在使用FooProxy时失效

任何见解都非常感谢!

NHibernate期货有时返回代理,有时返回实体

通常会发生这种情况的原因是,在此之前,在会话的其他地方加载了Foo,并且您正在获取基于先前查询创建的代理。

我在以下方面取得了一些成功

var fooProxy = foo as INHibernateProxy;
if(fooProxy != null) {
   var context= Session.GetSessionImplementation().PersistenceContext;
   foo = context.Unproxy(fooProxy);
}

虽然,在大多数情况下,序列化过程似乎将代理转换为正确的类型。