QueryOver具有动态连接和分离功能

时间:2016-05-30 07:42:35

标签: c# nhibernate

我需要创建一个查询,根据方法的输入,使用或不使用连接。鉴于以下模型:

Account
{
    Group Group;
    Account KeyUserInteral;
    Account KeyUserExternal;
    DateTime DeactivationDate;
}

Group
{
    Account KeyUserInteral;
    Account KeyUserExternal;
}

我想要

  • 将所有Accounts输入给定的Account <{1}}

  • 获取所有KeyUser输入给定的AccountsAccount 作为KeyUser输入{{1} }}

,具体取决于仅包含有效Account.Group的{​​{1}}过滤器。

为此,我尝试使用这种方法:

KeyUser

不幸的是,创建的SQL并不是我所需要的:(排除了DeactivationDate因为我觉得这并不是很有趣)

Accounts

我需要的是:

public IList<Account> ListByKeyUser(int keyUserId_, bool includeGroupAccounts_, bool onlyActive_)
{
    Account keyUser = Get(keyUserId_);

    Disjunction keyUserRestriction = new Disjunction();
    keyUserRestriction.Add<Account>(acc_ => acc_.KeyUserInternal == keyUser || acc_.KeyUserExternal == keyUser);

    IQueryOver<Account, Account> query = Session.QueryOver<Account>();

    if (includeGroupAccounts_) {
        query.JoinQueryOver(acc_ => acc_.Group, JoinType.LeftOuterJoin)
            .Where(grp_ => grp_.KeyUserInternal == keyUser || grp_.KeyUserExternal == keyUser);
    }

    query.Where(keyUserRestriction);

    if (onlyActive_) {
        query.Where(acc_ => acc_.DeactivationDate > DateTime.Now);
    }

    return query.OrderBy(acc_ => acc_.Name).Asc.List<Account>();
}

基本上,我只需要以某种方式移动&#34;加入条件&#34;进入&#34;或&#34;。我通过在分离中添加where来尝试它:

SELECT

但这会产生:

SELECT [...]
FROM accounts this_ left outer join groups group1_ on this_.userGroup=group1_.id
WHERE
(group1_.keyUserInternal = @p0 or group1_.keyUserExternal = @p1)
and
((this_.keyUserInternal = @p2 or this_.keyUserExternal = @p3))
and this_.deactivationDate > @p4
ORDER BY this_.name asc;

完全忽略SELECT [...] FROM accounts this_ left outer join groups group1_ on this_.userGroup=group1_.id WHERE ((group1_.keyUserInternal = @p0 or group1_.keyUserExternal = @p1) or (this_.keyUserInternal = @p2 or this_.keyUserExternal = @p3)) and this_.deactivationDate > @p4 ORDER BY this_.name asc; 加入...

我该如何做到这一点?

1 个答案:

答案 0 :(得分:0)

更多的挖掘作为解决方案返回以下内容:

if (includeGroupAccounts_) {
    Group groupAlias = null;
    query.JoinAlias(acc_ => acc_.Group, () => groupAlias, JoinType.LeftOuterJoin);
    keyUserRestriction.Add(() => groupAlias.KeyUserExternal == keyUser || groupAlias.KeyUserInternal == keyUser);
}

这导致了我需要的SQL,其中&#34;加入哪里&#34;包含在&#34;或&#34;中,而#34;日期时间检查&#34;仍然是&#34;和&#34;为了一切。

SELECT [...]
FROM accounts this_ left outer join groups groupalias1_ on this_.userGroup=groupalias1_.id
WHERE (
    (this_.keyUserInternal = @p0 or this_.keyUserExternal = @p1)
    or (groupalias1_.keyUserExternal = @p2 or groupalias1_.keyUserInternal = @p3)
)
and this_.deactivationDate > @p4
ORDER BY this_.name asc