为查询定义子选择

时间:2011-08-08 13:49:33

标签: nhibernate queryover

我确定我在这里遗漏了一些非常明显的东西 我想要实现的目标非常简单 -

我想要一个查询加载所有User而不保留他们的PostsFollowers集合。
在另一个查询中,我想要使用 SubSelect 初始化这些集合。

在第二个查询中使用Fetch(..)会发出左连接,这是我不想要的 我可以在映射中定义这些集合的提取策略,如此(流利地):

.Not.LazyLoad()
.Fetch.Subselect()

这会导致第二个查询以我想要的方式运行,但是我无法关闭第一个查询的.Not.LazyLoad()(我已经尝试了.Fetch(u => u.Posts).Lazy但是没有'似乎做了什么)。

我错过了什么?

1 个答案:

答案 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