使用Query Over解决Nhibernate中的重复关联路径错误

时间:2013-05-08 14:11:46

标签: nhibernate fluent-nhibernate nhibernate-criteria queryover

我有一些代码试图访问相同的关联路径两次,它们是真正相同的别名,但因为我使用查询对象,我将它们放在两个不同的地方,我不知道如何得到别名。

可能是一些代码可以清除混乱:

var privateBlogQuery = new BlogQuery()
    .ByUser(1)
    .RemoveHidden()
    .FetchUserDetails();


//<-------- In Blog Query object class: ------>

/// Gets all the private blogs the user has permissions to view
public BlogQuery ByUser(int userId)
{
    var authorisedUsers = null;

    this.Left.JoinQueryOver(r => r.AuthorisedUsers, () => authorisedUsers)
        .Where(r => r.User.Id == userId);

    return this;
}

/// Removes all private blogs user has marked to be hidden
public BlogQuery RemoveHidden()
{
    var authorisedUsers = null;

    this.Left.JoinQueryOver(r => r.AuthorisedUsers, () => authorisedUsers)
        .Where(r => !r.IsHidden);

    return this;
}

/// Loads up details of all users who have permission 
/// to view the private blog
public BlogQuery FetchUserDetails()
{
    var users = null;
    var authorisedUsers = null;

    this.Left.JoinQueryOver(r => r.AuthorisedUsers, () => authorisedUsers)
        .Left.JoinQueryOver(r => r.User, () => users);

    return this;
}

有时我单独使用所有3个标准,并且生成的sql正是我所需要的,只要它们被单独使用,一切都很好,花花公子。

现在我需要同时使用它们,并且nhibernate会抛出异常duplicate alias并且我更改了这三个函数的别名但是我接受了duplicate association path例外。

谷歌搜索和我learnt that it is a bug in hibernate,我也发现了一些workarounds on this bug

麻烦的是我正在使用Query对象,因此查询并且我不确定如何在此处获取关联路径/别名。

那我该怎么办呢?

1 个答案:

答案 0 :(得分:1)

  • authorisedUsers作为BlogQuery的成员变量,并使用标记/标记来了解ByUserRemoveHidden是否应该加入
  • 使用JoinAlias

例如

AuthorisedUser authorisedUser;
bool authorisedUsersJoined;

public BlogQuery RemoveHidden()
{
    if (!authorisedUsersJoined)
        this.Left.JoinAlias(r => r.AuthorisedUsers, () => authorisedUser);

    this.Where(() => !authorisedUser.IsHidden);

    return this;
}

FetchUserDetails与其他两个互斥,因为对关联的过滤会阻止NH初始化关联。您需要使用过滤器进行子查询并查询生成的ID并初始化。

/// Loads up details of all users who have permission 
/// to view the private blog
public BlogQuery FetchUserDetails()
{

    this.Query = QueryOver.Of<Blog>()
        .WhereRestrictionOn(b => b.Id).IsIn(this.Query.Select(b => b.Id))
        .Fetch(r => r.AuthorisedUsers).Eager
            .ThenFetch(au => au.User).Eager;

    return this;
}