我有一个数据库提取,使用多个未来查询处理完整的对象图。它看起来像这样(类名已被更改以保护无辜者):
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
非常感谢任何见解!
答案 0 :(得分:9)
通常会发生这种情况的原因是因为Foo会在此之前的会话中的其他位置加载,并且您将在上一个查询中创建代理。
我在以下
取得了一些成功var fooProxy = foo as INHibernateProxy;
if(fooProxy != null) {
var context= Session.GetSessionImplementation().PersistenceContext;
foo = context.Unproxy(fooProxy);
}
尽管如此,在大多数情况下,序列化过程似乎将代理转换为正确的类型。