2

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

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喂食 a 时返回 true FooProxy,所以我不能保证它不是这样的代理
  • 我是代理不利的,因为该图将被序列化以用于缓存目的和反序列化在使用时发出呱呱叫声FooProxy

非常感谢任何见解!

4

1 回答 1

9

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

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

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

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

于 2013-04-17T19:43:32.483 回答