Преобразование запроса HQL в критерии генерирует неверный SQL - PullRequest
0 голосов
/ 10 ноября 2009

Я пытаюсь преобразовать следующий HQL-запрос в критерии.

from SubportfolioAudit as a
where a.ID in (select max(a2.ID)
                from SubportfolioAudit as a2
                where a2.EffectiveDate = :EffectiveDate
                    and a.Subportfolio.ID = a2.Subportfolio.ID
                group by a2.Subportfolio.ID)
and a.Subportfolio.ID in (:SubportfolioList)

Пока у меня есть следующее:

var crit =  Session.CreateCriteria(typeof(SubportfolioAudit));
var currentAuditByEffectiveDate = DetachedCriteria.For(typeof(SubportfolioAudit))
                                  .SetProjection(Projections.ProjectionList()
                                                    .Add(Projections.Max("ID"))
                                                    .Add(Projections.GroupProperty("Subportfolio.ID")))
                                  .Add(Expression.Eq("EffectiveDate", effectiveDate));

crit.Add(Subqueries.PropertyIn("ID", currentAuditByEffectiveDate));
crit.Add(Expression.In("Subportfolio.ID", subportfolioList.Select(x => x.ID).ToArray()));

return crit.List<SubportfolioAudit>();

, который генерирует недопустимый подзапрос, вы можете увидеть его здесь:

SELECT this_.SubportfolioAuditId        as Subportf1_21_6_,
       this_.Event                      as Event21_6_,
       this_.CreatedDate                as CreatedD3_21_6_,
       this_.[User]                     as User4_21_6_,
       this_.EffectiveDate              as Effectiv5_21_6_,
       this_.SubportfolioId             as Subportf6_21_6_,
       subportfol2_.SubportfolioId      as Subportf1_12_0_,
       subportfol2_.PACERCode           as PACERCode12_0_,
       subportfol2_.HedgeRatio          as HedgeRatio12_0_,
       subportfol2_.Name                as Name12_0_,
       subportfol2_.Strategy            as Strategy12_0_,
       subportfol2_.BasketId            as BasketId12_0_,
       subportfol2_.PortfolioId         as Portfoli7_12_0_,
       subportfol2_.ReferenceBasketId   as Referenc8_12_0_,
       (SELECT CASE 
                 WHEN Count(* ) > 0
                 THEN 1
                 ELSE 0
               END
        FROM   Asset
        WHERE  Asset.SubportfolioId = subportfol2_.SubportfolioId) as formula1_0_,
       basket3_.BasketId                as BasketId7_1_,
       basket3_.Name                    as Name7_1_,
       basket3_.CatsBenchmarkCode       as CatsBenc4_7_1_,
       basket3_.Description             as Descript5_7_1_,
       basket3_.BaseBasketId            as BaseBask6_7_1_,
       basket3_.Filename                as Filename7_1_,
       basket3_.Type                    as Type7_1_,
       basket4_.BasketId                as BasketId7_2_,
       basket4_.Name                    as Name7_2_,
       basket4_.CatsBenchmarkCode       as CatsBenc4_7_2_,
       basket4_.Description             as Descript5_7_2_,
       basket4_.BaseBasketId            as BaseBask6_7_2_,
       basket4_.Filename                as Filename7_2_,
       basket4_.Type                    as Type7_2_,
       portfolio5_.PortfolioId          as Portfoli1_5_3_,
       portfolio5_.BaseCurrencyCode     as BaseCurr2_5_3_,
       portfolio5_.TradingAccountNumber as TradingA3_5_3_,
       portfolio5_.Name                 as Name5_3_,
       portfolio5_.ClientId             as ClientId5_3_,
       client6_.ClientId                as ClientId4_4_,
       client6_.ExplicitFee             as Explicit2_4_4_,
       client6_.Affiliated              as Affiliated4_4_,
       client6_.ClientGroup             as ClientGr4_4_4_,
       client6_.RCODA                   as RCODA4_4_,
       client6_.Name                    as Name4_4_,
       client6_.BaseCurrencyCode        as BaseCurr7_4_4_,
       client6_.Region                  as Region4_4_,
       basket7_.BasketId                as BasketId7_5_,
       basket7_.Name                    as Name7_5_,
       basket7_.CatsBenchmarkCode       as CatsBenc4_7_5_,
       basket7_.Description             as Descript5_7_5_,
       basket7_.BaseBasketId            as BaseBask6_7_5_,
       basket7_.Filename                as Filename7_5_,
       basket7_.Type                    as Type7_5_
FROM   dbo.SubportfolioAudit this_
       inner join dbo.Subportfolio subportfol2_
         on this_.SubportfolioId = subportfol2_.SubportfolioId
       left outer join dbo.Basket basket3_
         on subportfol2_.BasketId = basket3_.BasketId
       left outer join dbo.Basket basket4_
         on basket3_.BaseBasketId = basket4_.BasketId
       left outer join dbo.Portfolio portfolio5_
         on subportfol2_.PortfolioId = portfolio5_.PortfolioId
       left outer join dbo.Client client6_
         on portfolio5_.ClientId = client6_.ClientId
       left outer join dbo.Basket basket7_
         on subportfol2_.ReferenceBasketId = basket7_.BasketId
WHERE  this_.SubportfolioAuditId in (SELECT   max(this_0_.SubportfolioAuditId) as y0_,
                                              this_0_.SubportfolioId           as y1_
                                     FROM     dbo.SubportfolioAudit this_0_
                                     WHERE    this_0_.EffectiveDate = '2009-09-11T00:00:00.00' /* @p0 */
                                     GROUP BY this_0_.SubportfolioId)
       and this_.SubportfolioId in (13 /* @p1 */,14 /* @p2 */,15 /* @p3 */,16 /* @p4 */,
                                    17 /* @p5 */,18 /* @p6 */,19 /* @p7 */,20 /* @p8 */,
                                    21 /* @p9 */)

Я знаю, что Projection.GroupProperty () вызывает проблему, но я не могу найти другой способ выполнить то, что я хочу.

1 Ответ

1 голос
/ 10 ноября 2009

Я считаю (и исправьте меня, если я ошибаюсь), что подзапрос недействителен, потому что вы пропустили второе условие where, которое вы установили в своем HQL (... и a.Subportfolio.ID = a2.Subportfolio.ID ).

Преобразование вашего запроса Criteria, как показано ниже, я считаю (не могу проверить, так как не могу проверить ваш код), что это поможет.

var crit = Session.CreateCriteria(typeof(SubportfolioAudit), "mainQuery");
var currentAuditByEffectiveDate = DetachedCriteria.For(typeof(SubportfolioAudit),"subQuery")
              .SetProjection(Projections.ProjectionList()
                                .Add(Projections.Max("ID"))
                                .Add(Projections.GroupProperty("Subportfolio.ID")))
              .Add(Expression.Eq("EffectiveDate", effectiveDate));
              .Add(Expression.EqProperty("subQuery.ID", "mainQuery.ID"));

crit.Add(Subqueries.PropertyIn("mainQuery.ID", currentAuditByEffectiveDate));
crit.Add(Expression.In("mainQuery.Subportfolio.ID", subportfolioList.Select(x => x.ID).ToArray()));

return crit.List<SubportfolioAudit>();

Что я сделал, так это добавил дополнительное условие where в DetachedCriteria, которое «связывает» столбец SubportfoliAudit.ID подзапроса с внешним основным запросом. Я также предоставил псевдонимы для имен запросов.

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