我想覆盖默认的延迟加载行为,该行为在映射中设置为“lazy=false”。无法更改它,因为现有应用程序的许多部分都依赖于此设置。
花了几个小时后我没有找到解决方案,所以我在这里询问。
如何做到这一点?
我想要实现的是微调我的查询以仅加载需要的内容。
这是我已经尝试过的:
使用QueryOver
API:
var properties = session.QueryOver<Property>()
.Fetch(prop => prop.Transactions).Eager
.Fetch(prop => prop.Districts).Eager
//I dont want to load those entities below so I mark
//them as lazy - IT DOESN'T WORK
//I can see in SQL that they are getting loaded in separate queries
.Fetch(prop => prop.Districts.First().Aliases).Lazy
.Fetch(prop => prop.Districts.First().PolygonPoints).Lazy
.Skip(i * pageSize)
.Take(pageSize)
.List();
使用Criteria
API:
var criteria = session.CreateCriteria<Property>();
criteria.SetFetchMode("Transactions", NHibernate.FetchMode.Join);
criteria.SetFetchMode("Districts", NHibernate.FetchMode.Join);
criteria.SetFetchMode("Districts.Aliases", NHibernate.FetchMode.Select); // tried Lazy too
criteria.SetFetchMode("Districts.PolygonPoints", NHibernate.FetchMode.Select); // tried Lazy too
criteria.AddOrder(NHibernate.Criterion.Order.Asc("Id"));
criteria.SetFirstResult(i * pageSize);
criteria.SetMaxResults(pageSize);
var properties = criteria.List<Property>();
使用上述任何方法,在调用 List<>()
时始终会加载“别名”和“多边形点” 。我的流程中不需要它们。
我正在使用 Nhibernate 4.0。
有什么想法吗?
最佳答案
在这种情况下,我们无法覆盖映射。我们可以以相反的方式做到这一点 - 放置惰性 - 并使用急切的获取进行查询。
决策过程(引用加载)
是在查询之外事后完成的。所以它可以被预加载,但无法避免。
这里的解决方案可以有两种类型。
- 第一个是首选(我) - 尽力而为,让懒惰成为默认:Ayende - NHibernate is lazy, just live with it
- 使用
投影
。指示 NHibernate 仅创建一个查询,使用转换器获取预期的对象图 - 其中不包含任何代理
有一个非常清楚的示例如何(正确)使用投影列表,甚至用于引用:
我们还需要自定义结果转换器,它将事后根据返回的数据创建所有引用:
关于nhibernate - 覆盖延迟加载行为 'lazy=false',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30166946/