使用NHibernate进行多个连接查询和桥接表

时间:2012-01-30 22:41:06

标签: nhibernate

除了NHibernate的基本用法之外,我比较新。我想知道是否有人可以帮我制定以下场景的代码:

表格结构

用户配置

UserProfile_SubTableA_Bridge

SubTableA

UserProfile_SubTableB_Bridge

SubTableB

我正在尝试构建一个完成此任务的查询:

FetchAllNotDeleted(IEnumerable<SubTableB> SelectedA, IEnumerable<SubTableB> SelectedB)
{
  select * from UserProfile
  left join SubTable1_Bridge A
  left join SubTable2_Bridge B
  where 
  A.Id in(SelectedA)
  OR B.Id in (SelectedB)

  return Query().Future();
}

这在普通的sql中看起来很简单,但我不知道如何使用NHib来制定这个查询。

如果我想根据SelectedA或SelectedB是否为空来有条件地添加联接怎么办?类似的东西:

if( selectedA != null ) { /* add join and restrictions for A */}
if( selectedB != null ) { /* add join and restrictions for B */}

我尝试了以下内容,但它已经接近了,但是它“和”在一起而不是“或”

if (selectedA != null)
{
var selectedIds = selectedA.Select(x => x.Id.ToString()).ToList();
query.JoinQueryOver(x => x.SubA, JoinType.LeftOuterJoin).And(
        Restrictions.Disjunction().Add(
            Restrictions.In("Id", selectedIds)
        )
    );
}

if (selectedB != null)
{
    var selectedIds = selectedB.Select(x => x.Id.ToString()).ToList();
    query.JoinQueryOver(x => x.SubB, JoinType.LeftOuterJoin).And(
            Restrictions.Disjunction().Add(
                Restrictions.In("Id", selectedIds)
            )
        );
}

1 个答案:

答案 0 :(得分:0)

Sub1Entity sub1 = null;
Sub1Entity sub2 = null;

session.QueryOver<UserProfile>()
    .JoinAlias(up => up.Sub1, () => sub1)
    .JoinAlias(up => up.Sub2, () => sub2)
    .Where(Restrictions.Or(
        Restrictions.In(Projections.Property(() => sub1.Id), SelectedA),
        Restrictions.In(Projections.Property(() => sub2.Id), SelectedB))
    .Future();

更新:有条件

var query = session.QueryOver<UserProfile>();
Disjunction or = null;

if( selectedA != null )
{
    Sub1Entity sub1 = null;
    query = query.JoinAlias(up => up.Sub1, () => sub1)
    or = (or ?? new Disjunction()).Add(Restrictions.In(Projections.Property(() => sub1.Id), SelectedA));
}

if( selectedB != null )
{
    Sub2Entity sub2 = null;
    query = query.JoinAlias(up => up.Sub2, () => sub2)
    or = (or ?? new Disjunction()).Add(Restrictions.In(Projections.Property(() => sub2.Id), SelectedB));
}

if (or != null)
    query = query.Where(or);

return query.Future();