Вложенный запрос выбора количества с критериями - PullRequest
1 голос
/ 06 июля 2010

говорят, что у нас есть 2 объекта EntityA и EntityB со связанными таблицами, TableA и TableB.

Я должен реализовать этот запрос:

select a.Id , (select count(b.Id) from TableB b where b.FKa = a.Id and b.AnotherField > 0) as TheCount
from TableA a 

Я очень близок к этому, так как написал этот код:

var subCrit = DetachedCriteria.For<EntityB>
                                        .Add<EntityB>(e => e.AnotherField > 0)
                                        .SetProjection(LambdaProjection.Count<EntityB>(e => e.Id).As("TheCount"));

var crit = Session.CreateCriteria<EntityA>
                        .SetProjection(LambdaProjection.GroupProperty<EntityA>(e => e.Id).As("Id),
                                            Projections.SubQuery(subCrit));

если я выполню этот критерий, я получу следующий SQL:

select a.Id as Id , (select count(b.Id) from TableB b where b.AnotherField > 0) as TheCount from TableA a

как вы можете видеть, это очень близко к тому, чего я пытаюсь достичь ... проблема (и это определенно большая проблема: D) в том, что нет никакой связи между подзапросом и сущностями TableA (где b.FKa = a.Id). Я не могу найти способ соотнести подзапрос с внешним запросом по критериям.

Есть предложения?

Та много

Alessandro

EDIT:

меняя точку зрения, я тоже мог бы сделать что-то подобное:

 var crit = Session.CreateCriteria<EntityA>()
                   .CreateAlias<EntityB>(a => a.B, () => b);
                   .SetProjection(LambdaProjection.Count<A>(a => b.Id).As("TheCount"),
                   .SetProjection(LambdaProjection.GroupProperty<EntityA>(a => a.Id));

и генерируется следующий sql:

select count(b.Id) as TheCount, a.Id as IDa
from TableA a left outer join TableB b
on a.Id = b.FKa
group by a.Id

но здесь вы можете видеть, что дополнительное условие where b.AnotherField> 0 отсутствует, и я не знаю, как вставить его только для подсчета.

Надеюсь, это понятно, еще раз спасибо

Ответы [ 2 ]

3 голосов
/ 07 июля 2010

Вот решение:

var condition = Expression.Gt("b.AnotherField",0);
var conditionalProjection = Projections.Conditional(condition, Projections.Constant(1), Projections.Constant(0));

crit = Session.CreateCriteria<EntityA>()
                   .CreateAlias<EntityB>(a => a.B, () => b);
                   .SetProjection(Projections.Count(conditionalProjection).As("TheCount"),
                     (LambdaProjection.GroupProperty<EntityA>(a => a.Id));

и это сгенерированный sql:

выберите количество (случай b.AnotherField> 0, затем 1 или 0 end) как TheCount, a.Идентификатор из таблицы A внутреннего соединения TableB b

надеюсь, что это может быть полезно

ура

Алессандро

enter code here
0 голосов
/ 06 июля 2010

Я предлагаю изменить SQL-оператор

ВЫБРАТЬ a.is, count (a.id) ИЗ TableA a ПРИСОЕДИНЯЙСЯ TableB b ON a.id = b.fka AND b.af> 0 GROUP bya.ID

и создайте для него простые критерии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...