我确定我在这里遗漏了一些非常明显的东西 我想要实现的目标非常简单 -
我想要一个查询加载所有User
而不保留他们的Posts
和Followers
集合。
在另一个查询中,我做想要使用 SubSelect 初始化这些集合。
在第二个查询中使用Fetch(..)
会发出左连接,这是我不想要的
我可以在映射中定义这些集合的提取策略,如此(流利地):
.Not.LazyLoad()
.Fetch.Subselect()
这会导致第二个查询以我想要的方式运行,但是我无法关闭第一个查询的.Not.LazyLoad()
(我已经尝试了.Fetch(u => u.Posts).Lazy
但是没有'似乎做了什么)。
我错过了什么?
答案 0 :(得分:3)
我通常在我的映射中设置lazy=true
(Ayende wrote about it)因为我更喜欢控制代码中的行为。
这样做只有在你需要时,你的协会才会被保湿。
var users = session.QueryOver<User>()
.List();
除非您访问该集合的元素,否则将加载所有用户但不会加载其帖子:
var postTitle = users[0].Posts[0].Title;
如果您想加载一些用户及其帖子,您可以执行以下操作:
Post posts = null;
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Inner.JoinAlias(t => t.Posts, () => posts)
.List();
或:
Post posts = null;
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Inner.JoinQueryOver(t => t.Posts, () => posts)
.List();
您可能已经注意到使用Fetch Eager:
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Fetch(x=>x.Posts).Eager
.List();
使用您不想要的外部联接。
前两个示例会出现您在评论中提到的问题。
如果您想通过QueryOver在结果中避免使用笛卡尔积,可以使用.TransformUsing(Transformers.DistinctRootEntity)
:
Post posts = null;
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Inner.JoinAlias(t => t.Posts, () => posts)
.TransformUsing(Transformers.DistinctRootEntity)
.List();
您可以找到更多信息here。