HQL join проблема - PullRequest
       2

HQL join проблема

0 голосов
/ 03 августа 2011

У меня нет проблем с написанием sql для следующей проблемы. Тем не менее, я хотел бы написать это как HQL или ICriteria. Я использую свободный nhibernate и последний nhibernate. Ситуация:

Есть 6 классов A B C D AC AD. B наследуется от A. AC представляет отношение m: m между A и C, а AD представляет отношение m: m между A и D. Предположим, что все классы имеют столбец ID. Я хотел бы посчитать количество Cs и Ds B, связанных с.

Не существует IList, например, Cs в A (и B в этом отношении). Тем не менее классы связаны ...

Вот код (упрощенно):

public class A : Entity
{

}

public class B : A
{

}

public class C : Entity
{

}

public class D : Entity
{

}

public class AC : Entity
{
    public virtual A A { get; set; }
    public virtual C C { get; set; }
}

public class AD : Entity
{
    public virtual A A { get; set; }
    public virtual D D { get; set; }
}

Возможно ли в моем конкретном случае использовать HQL и «левое соединение» (чтобы также показать B с нулевыми C и D)?

Спасибо.

Christian

PS:

Я немного играл с тета-стилями, но не получил ожидаемых результатов, и я не думаю, что здесь возможны "левые", не так ли?

PPS:

Этот вид объединения в тета-стиле работает, но только если B ассоциируется как минимум с 1 C и D:

select 
    B.Id, 
    count(distinct AC.C.Id),
    count(distinct AD.D.Id)
from AC AC, AD AD, B B
where AC.A.Id = B.Id and AD.A.Id = B.Id
group by B.Id

1 Ответ

1 голос
/ 03 августа 2011

Вы можете использовать два запроса и суммировать результат:

int numberOfLinks;

numberOfLinks = session
  .CreateQuery(
    @"select count(*)
    from AC ac
    where ac.A = :b"
  .SetEntity("b", myB)
  .UniqueResult<int>();

numberOfLinks += session
  .CreateQuery(
    @"select count(*)
    from AD ad
    where ad.A = :b"
  .SetEntity("b", myB);

Я не вижу способа сделать это с помощью одного запроса. Кажется, что ваши классы не предназначены для такого рода запросов ... (что может быть признаком того, что дизайн не подходит, но не должен быть. этот запрос для вашего приложения.)


Напротив, если у вас было эти пути навигации, не задавая вопросов относительно классов отношений:

public class A : Entity
{
  IList<AC> ACs { get; private set; }
  IList<AD> ADs { get; private set; }
}

Вы получите размер списков по:

numberOfLinks = session.CreateQuery(
  @"select size(ACs) + size(ADs)
  from B
  where ...")

или даже проще в памяти: -)

numberOfLinks = myB.ADs.Count + myB.ACs.Count;

Полностью удаляя классы отношений, это может выглядеть так:

public class A : Entity
{
  IList<C> Cs { get; private set; }
  IList<D> Ds { get; private set; }
}

public class C : Entity
{
  IList<A> As { get; private set; }
}

public class D : Entity
{
  IList<A> As { get; private set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...